title: Convert ASCII to unicode string in C/C++ (APIless)
body: <p>I know I <a href="https://stackoverflow.com/questions/11576846/convert-ascii-string-to-unicode-windows-pure-c">can</a> convert ASCII to unicode strings using <code>MultiByteToWideChar</code> but I want an APIless solution. The only difference is that unicode is 2 bytes compared to ASCII, which is 1.</p>
  
  <p>Should be something like the following, but it doesn't work.</p>
  
  <p>The problem is:</p>
  
  <p><a href="https://i.stack.imgur.com/2skbR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2skbR.png" alt="enter image description here"></a></p>
  
  <pre class="lang-cpp prettyprint-override"><code>void* __malloc(size_t size)
  {
     return HeapAlloc(GetProcessHeap(), 0, size); 
  }
  
  void __free(void* p)
  {
     if (p) HeapFree(GetProcessHeap(), 0, p); 
  }
  
  wchar_t* ascii_to_unicode(const char* ascii)
  {
      if (!ascii)
          return nullptr;
  
      size_t len;
      wchar_t* unicode;
  
      len = strlen(ascii) * 2 + 1;
      if (!(unicode = reinterpret_cast&lt;wchar_t*&gt;(__malloc(len))))
          return nullptr;
  
      for (size_t i = 0; i &lt; len; i++)
          *unicode++ = static_cast&lt;wchar_t&gt;(*ascii++);
  
      return unicode;
  }
  
  char* unicode_to_ascii(const wchar_t* unicode)
  {
      if (!unicode)
          return nullptr;
  
      size_t len;
      char* ascii;
  
      len = wcslen(unicode) / 2 + 1;
      if (!(ascii = reinterpret_cast&lt;char*&gt;(__malloc(len))))
          return nullptr;
  
      for (size_t i = 0; i &lt; len; i++)
          *ascii++ = static_cast&lt;char&gt;(*unicode++);
  
      return ascii;
  }
  </code></pre>
  
  <p>I wanted to convert the ASCII returned by <code>strdup</code> to my custom get_module_handle function. </p>
  
  <pre class="lang-cpp prettyprint-override"><code>char* forwardLib = strdup(address);
  char* forwardName = _strchr(forwardLib, '.');
  *forwardName++ = 0;
  
  get_module_handle(ascii_to_unicode(forwardLib));
  
  //
  void* get_module_handle(const wchar_t* moduleName)
  {
  #if defined _M_IX86
      PPEB pPEB = reinterpret_cast&lt;PPEB&gt;(__readfsdword(0x30));
  #elif defined _M_X64
      PPEB pPEB = reinterpret_cast&lt;PPEB&gt;(__readgsqword(0x60));
  #endif
  
      for (PLIST_ENTRY pListEntry = pPEB-&gt;Ldr-&gt;InMemoryOrderModuleList.Flink; pListEntry &amp;&amp; pListEntry != &amp;pPEB-&gt;Ldr-&gt;InMemoryOrderModuleList; pListEntry = pListEntry-&gt;Flink)
      {
          PLDR_DATA_TABLE_ENTRY pLdrDataTableEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
  
          if (!__wcsicmp(pLdrDataTableEntry-&gt;BaseDllName.Buffer, moduleName))
              return pLdrDataTableEntry-&gt;DllBase;
      }
  
      return nullptr;
  }
  </code></pre>