Ejemplo n.º 1
0
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst,
		size_t dst_size)
{
	size_t in_len;
	size_t out_len;

	if (!str)
		return 0;

	in_len = (len != 0) ? len : wcslen(str);
	out_len = dst ? (dst_size - 1) : wchar_to_utf8(str, in_len, NULL, 0, 0);

	if (dst) {
		if (!dst_size)
			return 0;

		if (out_len)
			out_len = wchar_to_utf8(str, in_len,
					dst, out_len + 1, 0);

		dst[out_len] = 0;
	}

	return out_len;
}
Ejemplo n.º 2
0
void dstr_from_wcs(struct dstr *dst, const wchar_t *wstr)
{
	size_t len = wchar_to_utf8(wstr, 0, NULL, 0, 0);

	if (len) {
		dstr_resize(dst, len);
		wchar_to_utf8(wstr, 0, dst->array, len+1, 0);
	} else {
		dstr_free(dst);
	}
}
Ejemplo n.º 3
0
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst)
{
	size_t in_len = (len != 0) ? len : wcslen(str);
	size_t out_len = dst ? len : wchar_to_utf8(str, in_len, NULL, 0, 0);

	if (out_len && dst) {
		wchar_to_utf8(str, in_len, dst, out_len+1, 0);
		dst[out_len] = 0;
	}

	return out_len;
}
Ejemplo n.º 4
0
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char **pstr)
{
	size_t in_len = (len != 0) ? len : wcslen(str);
	size_t out_len = wchar_to_utf8(str, in_len, NULL, 0, 0);
	char *dst = NULL;

	if (out_len) {
		dst = bmalloc(out_len+1);
		wchar_to_utf8(str, in_len, dst, out_len+1, 0);
		dst[out_len] = 0;
	}

	*pstr = dst;
	return out_len;
}
Ejemplo n.º 5
0
void hpdf_doc::text_out_cjk(HPDF_REAL& f_xpos, HPDF_REAL& f_ypos, wstring out_string, HPDF_REAL& f_advance, HPDF_REAL f_width, HPDF_REAL f_gap, HPDF_REAL f_space)
{
	char line[4];
	memset(line, 0, 4);

	int n_TX = (et_cp.TX > 0) ? et_cp.TX : et_cp.T,
		n_TY = (et_cp.TY > 0) ? et_cp.TY : et_cp.T;

	HPDF_REAL font_height = MMTEXT2PTX((et_cp.Z * n_TY));
	HPDF_REAL font_width = MMTEXT2PTX((et_cp.W * n_TX / 2) + (et_cp.X / 2));
	HPDF_REAL ygap = MMTEXT2PTX(et_cp.L);
	HPDF_REAL xpos = f_xpos, ypos = f_ypos;

	int len = out_string.length();
	if (et_cp.VorH == 'V')
	{
		xpos += (f_width + f_gap) * 2;
		ypos -= font_width;
	}

	for (int i = 0; i < len; i++)
	{
		wchar_t out_wchar = out_string[i];
		size_t size = wchar_to_utf8(&out_wchar, 1, line, 4, NULL);
		if (size == 0) break;

		HPDF_Page_TextOut(h_current_page, xpos + f_advance, ypos - f_linespace, line);
		f_advance += (et_cp.VorH == 'V') ? (font_height) : (f_width + f_gap) * 2;
		//f_advance += (f_width + f_gap) * 2;
	}

}
Ejemplo n.º 6
0
// eng: Finds the next ptc-file in emitters folder
// rus: Поиск следующего ptc-файла в папке с эмиттерами
const char* MP_Platform_WIN_POSIX::GetNextFile()
{
	#ifdef _WINDOWS

	if (FindNextFileW(hFindFile,&fd))
	{
		file=wchar_to_utf8(fd.cFileName);
		return file.c_str();
	}
	FindClose(hFindFile);

	#else

	dirent* result=readdir(dir);
	while(result)
	{
		int len=strlen(result->d_name);
		if (len>4)
		{
			const char* ext=&(result->d_name[len-4]);
			if (strcmp(ext, ".ptc")==0)
			{
				return result->d_name;
			}
		}
		result=readdir(dir);
	}
	closedir(dir);
	dir=NULL;
	
	#endif

	return NULL;
}
Ejemplo n.º 7
0
// eng: Finds the first ptc-file in emitters folder
// rus: Поиск первого ptc-файла в папке с эмиттерами
const char* MP_Platform_WIN_POSIX::GetFirstFile()
{
	std::string ptc_path=GetPathToPTC();

	#ifdef _WINDOWS
	ptc_path+="*.ptc";
	const wchar_t* mask=utf8_to_wchar(ptc_path.c_str());
	hFindFile=FindFirstFileW(mask,&fd);
	if (hFindFile!=INVALID_HANDLE_VALUE)
	{
		file=wchar_to_utf8(fd.cFileName);
		return file.c_str();
	}
	FindClose(hFindFile);

	#else

	dir=opendir(ptc_path.c_str());
	if (dir)
		return GetNextFile();

	#endif

	return NULL;
}
Ejemplo n.º 8
0
DWORD request_ui_get_keys_utf8(Remote *remote, Packet *request)
{
	Packet *response = packet_create_response(request);
	DWORD result = ERROR_SUCCESS;
	char *utf8_keyscan_buf = NULL;

	if (tKeyScan) {
		utf8_keyscan_buf = wchar_to_utf8(g_keyscan_buf);
		packet_add_tlv_raw(response, TLV_TYPE_KEYS_DUMP, (LPVOID)utf8_keyscan_buf,
			(DWORD)strlen(utf8_keyscan_buf) + 1);
		memset(g_keyscan_buf, 0, KEYBUFSIZE);

		// reset index and zero active window string so the current one
		// is logged again
		g_idx = 0;
		RtlZeroMemory(g_prev_active_image, MAX_PATH);
	}
	else {
		result = 1;
	}

	// Transmit the response
	packet_transmit_response(result, remote, response);
  free(utf8_keyscan_buf);
	return ERROR_SUCCESS;
}
Ejemplo n.º 9
0
std::string wchar_to_utf8_cstr(const wchar_t *str)
{
	char *utf=wchar_to_utf8(str);
	std::string res(utf);
	free(utf);
	return res;
}
Ejemplo n.º 10
0
/* The okay button has been clicked or the enter enter key in the text
   field.  */
static void
ok_button_clicked (HWND dlg, pinentry_t pe)
{
    char *s_utf8;
    wchar_t *w_buffer;
    size_t w_buffer_size = 255;
    unsigned int nchar;

    pe->locale_err = 1;
    w_buffer = secmem_malloc ((w_buffer_size + 1) * sizeof *w_buffer);
    if (!w_buffer)
        return;

    nchar = GetDlgItemTextW (dlg, IDC_PINENT_TEXT, w_buffer, w_buffer_size);
    s_utf8 = wchar_to_utf8 (w_buffer, nchar, 1);
    secmem_free (w_buffer);
    if (s_utf8)
    {
        passphrase_ok = 1;
        pinentry_setbufferlen (pe, strlen (s_utf8) + 1);
        if (pe->pin)
            strcpy (pe->pin, s_utf8);
        secmem_free (s_utf8);
        pe->locale_err = 0;
        pe->result = pe->pin? strlen (pe->pin) : 0;
    }
}
Ejemplo n.º 11
0
BOOL XFile::WriteAsUTF8(CTSTR lpBuffer, DWORD dwElements)
{
    DWORD retVal = 0;

    if(!lpBuffer)
        return false;

    if (!hFile) return false;

    if (!lpBuffer[0])
        return true;

    if(!dwElements)
        dwElements = slen(lpBuffer);

#ifdef UNICODE
    DWORD dwBytes = (DWORD)wchar_to_utf8_len(lpBuffer, dwElements, 0);
    LPSTR lpDest = (LPSTR)Allocate(dwBytes+1);

    if (wchar_to_utf8(lpBuffer, dwElements, lpDest, dwBytes, 0))
        retVal = (Write(lpDest, dwBytes) == dwBytes);
    else
        Log(TEXT("XFile::WriteAsUTF8: wchar_to_utf8 failed: %d"), GetLastError());

    Free(lpDest);
#else
    DWORD retVal = (Write(lpBuffer, dwElements) == dwBytes);
#endif

    return retVal;
}
Ejemplo n.º 12
0
/*
 * Converts a name + ext UTF-8 pair to a valid MS filename.
 * Returned string is allocated and needs to be freed manually
 */
char* to_valid_filename(char* name, char* ext)
{
	size_t i, j, k;
	BOOL found;
	char* ret;
	wchar_t unauthorized[] = L"\x0001\x0002\x0003\x0004\x0005\x0006\x0007\x0008\x000a"
		L"\x000b\x000c\x000d\x000e\x000f\x0010\x0011\x0012\x0013\x0014\x0015\x0016\x0017"
		L"\x0018\x0019\x001a\x001b\x001c\x001d\x001e\x001f\x007f\"*/:<>?\\|,";
	wchar_t to_underscore[] = L" \t";
	wchar_t *wname, *wext, *wret;

	if ((name == NULL) || (ext == NULL)) {
		return NULL;
	}

	if (strlen(name) > WDI_MAX_STRLEN) return NULL;

	// Convert to UTF-16
	wname = utf8_to_wchar(name);
	wext = utf8_to_wchar(ext);
	if ((wname == NULL) || (wext == NULL)) {
		safe_free(wname); safe_free(wext); return NULL;
	}

	// The returned UTF-8 string will never be larger than the sum of its parts
	wret = (wchar_t*)calloc(2*(wcslen(wname) + wcslen(wext) + 2), 1);
	if (wret == NULL) {
		safe_free(wname); safe_free(wext); return NULL;
	}
	wcscpy(wret, wname);
	safe_free(wname);
	wcscat(wret, wext);
	safe_free(wext);

	for (i=0, k=0; i<wcslen(wret); i++) {
		found = FALSE;
		for (j=0; j<wcslen(unauthorized); j++) {
			if (wret[i] == unauthorized[j]) {
				found = TRUE; break;
			}
		}
		if (found) continue;
		found = FALSE;
		for (j=0; j<wcslen(to_underscore); j++) {
			if (wret[i] == to_underscore[j]) {
				wret[k++] = '_';
				found = TRUE; break;
			}
		}
		if (found) continue;
		wret[k++] = wret[i];
	}
	wret[k] = 0;
	ret = wchar_to_utf8(wret);
	safe_free(wret);
	return ret;
}
Ejemplo n.º 13
0
std::string hresult_error_string(HRESULT error) {
  LocalPtr<WCHAR> message;
  DWORD result = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
                                NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&message.ptr, 0, NULL);

  if (!result)
    return "Unknown error";

  return wchar_to_utf8(message.ptr);
}
Ejemplo n.º 14
0
DWORD
GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer)
{
  wchar_t dummy[1];
  DWORD len;

  len = GetTempPathW (0, dummy);
  if (len == 0)
    return 0;

  assert (len <= MAX_PATH);

  /* Better be safe than sorry.  MSDN doesn't say if len is with or
     without terminating 0.  */
  len++;

  {
    wchar_t *buffer_w;
    DWORD len_w;
    char *buffer_c;
    DWORD len_c;

    buffer_w = malloc (sizeof (wchar_t) * len);
    if (! buffer_w)
      return 0;

    len_w = GetTempPathW (len, buffer_w);
    /* Give up if we still can't get at it.  */
    if (len_w == 0 || len_w >= len)
      {
        free (buffer_w);
        return 0;
      }

    /* Better be really safe.  */
    buffer_w[len_w] = '\0';

    buffer_c = wchar_to_utf8 (buffer_w);
    free (buffer_w);
    if (! buffer_c)
      return 0;

    /* strlen is correct (not _mbstrlen), because we want storage and
       not string length.  */
    len_c = strlen (buffer_c) + 1;
    if (len_c > nBufferLength)
      return len_c;

    strcpy (lpBuffer, buffer_c);
    free (buffer_c);
    return len_c - 1;
  }
}
Ejemplo n.º 15
0
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst,
		size_t dst_size)
{
	size_t in_len = (len != 0) ? len : wcslen(str);
	size_t out_len = dst ? len : wchar_to_utf8(str, in_len, NULL, 0, 0);

	if (out_len && dst) {
		if (!dst_size)
			return 0;

		if (out_len) {
			if ((out_len + 1) > dst_size)
				out_len = dst_size - 1;

			wchar_to_utf8(str, in_len, dst, out_len + 1, 0);
		}

		dst[out_len] = 0;
	}

	return out_len;
}
Ejemplo n.º 16
0
BOOL XFile::WriteStr(CWSTR lpBuffer)
{
    assert(lpBuffer);

    if(!hFile) return XFILE_ERROR;

    DWORD dwElements = (DWORD)wcslen(lpBuffer);

    char lpDest[4096];
    DWORD dwBytes = (DWORD)wchar_to_utf8(lpBuffer, dwElements, lpDest, 4095, 0);
    DWORD retVal = (Write(lpDest, dwBytes) == dwBytes);

    return retVal;
}
Ejemplo n.º 17
0
/*
 * Parse a buffer (ANSI or UTF-8) and return the data for the 'n'th occurrence of 'token'
 * The returned string is UTF-8 and MUST be freed by the caller
 */
char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size)
{
	unsigned int j, curly_count;
	wchar_t *wtoken = NULL, *wdata = NULL, *wbuffer = NULL, *wline = NULL;
	size_t i;
	BOOL done = FALSE;
	char* ret = NULL;

	// We're handling remote data => better safe than sorry
	if ((token == NULL) || (buffer == NULL) || (buffer_size <= 4) || (buffer_size > 65536))
		goto out;

	// Ensure that our buffer is NUL terminated
	if (buffer[buffer_size-1] != 0)
		goto out;

	wbuffer = utf8_to_wchar(buffer);
	wtoken = utf8_to_wchar(token);
	if ((wbuffer == NULL) || (wtoken == NULL))
		goto out;

	// Process individual lines (or multiple lines when between {}, for RTF)
	for (i=0,j=0,done=FALSE; (j!=n)&&(!done); ) {
		wline = &wbuffer[i];

		for(curly_count=0;((curly_count>0)||((wbuffer[i]!=L'\n')&&(wbuffer[i]!=L'\r')))&&(wbuffer[i]!=0);i++) {
			if (wbuffer[i] == L'{') curly_count++;
			if (wbuffer[i] == L'}') curly_count--;
		}
		if (wbuffer[i]==0) {
			done = TRUE;
		} else {
			wbuffer[i++] = 0;
		}
		wdata = get_token_data_line(wtoken, wline);
		if (wdata != NULL) {
			j++;
		}
	}
out:
	if (wdata != NULL)
		ret = wchar_to_utf8(wdata);
	safe_free(wbuffer);
	safe_free(wtoken);
	return ret;
}
Ejemplo n.º 18
0
DWORD XFile::WriteStr(WSTR lpBuffer)
{
    traceInFast(XFile::WriteStr);

    assert(lpBuffer);

    if(!hFile) return XFILE_ERROR;

    DWORD dwElements = slen(lpBuffer);

    char lpDest[4096];
    DWORD dwBytes = (DWORD)wchar_to_utf8(lpBuffer, dwElements, lpDest, 4095, 0);
    DWORD retVal = Write(lpDest, dwBytes);

    return retVal;

    traceOutFast;
}
Ejemplo n.º 19
0
// eng: Returns path to folder which could be used by wrapper to store temporary files. If NULL is returned the temporary files are saved in RAM.
// rus: Возвращает путь к временной папке. Если вернуть NULL, то временные файлы будут сохраняться в ОЗУ.
const char* MP_Platform_WIN_POSIX::GetPathToTemp()
{
	#ifdef _WINDOWS
	if (temp_path.empty())
	{
		wchar_t path[MAX_PATH];
		GetTempPathW(MAX_PATH, path);
		temp_path=wchar_to_utf8(path);
	}

	return temp_path.c_str();

	#else

	return NULL;
    
	#endif
}
Ejemplo n.º 20
0
int fs_getwd(char **dir)
{
	int rc = ERROR_SUCCESS;
	wchar_t dir_w[FS_MAX_PATH];

	if (GetCurrentDirectoryW(FS_MAX_PATH, dir_w) == 0) {
		rc = GetLastError();
		goto out;
	}

	*dir = wchar_to_utf8(dir_w);
	if (*dir == NULL) {
		rc = GetLastError();
	}

out:
	return rc;
}
Ejemplo n.º 21
0
void tagUpdateCachedEntryWithRequest(sqlite3_stmt * request, TAG_VERBOSE * newData, uint nbData)
{
	for(uint i = 0; i < nbData; i++)
	{
		//We get a UTF8 version of the name
		size_t length = wstrlen((charType *) newData[i].name);
		char utf8[4 * length + 1];
		length = wchar_to_utf8((charType *) newData[i].name, length, utf8, 4 * length + 1, 0);

		//We submit the data to the request, then run and clean it
		sqlite3_bind_int(request, 1, (int32_t) newData[i].ID);
		sqlite3_bind_text(request, 2, utf8, (int32_t) length, SQLITE_STATIC);
		
		sqlite3_step(request);
		sqlite3_reset(request);
	}

	destroyRequest(request);
}
Ejemplo n.º 22
0
char * fs_expand_path(const char *regular)
{
	wchar_t expanded_path[FS_MAX_PATH];
	wchar_t *regular_w;

	regular_w = utf8_to_wchar(regular);
	if (regular_w == NULL) {
		return NULL;
	}

	if (ExpandEnvironmentStringsW(regular_w, expanded_path, FS_MAX_PATH) == 0) {
		free(regular_w);
		return NULL;
	}

	free(regular_w);

	return wchar_to_utf8(expanded_path);
}
Ejemplo n.º 23
0
/*
 * Parse a file (ANSI or UTF-8 or UTF-16) and return the data for the first occurrence of 'token'
 * The returned string is UTF-8 and MUST be freed by the caller
 */
char* get_token_data_file(const char* token, const char* filename)
{
	wchar_t *wtoken = NULL, *wdata= NULL, *wfilename = NULL;
	wchar_t buf[1024];
	FILE* fd = NULL;
	char *ret = NULL;

	if ((filename == NULL) || (token == NULL))
		return NULL;
	if ((filename[0] == 0) || (token[0] == 0))
		return NULL;

	wfilename = utf8_to_wchar(filename);
	if (wfilename == NULL) {
		uprintf(conversion_error, filename);
		goto out;
	}
	wtoken = utf8_to_wchar(token);
	if (wfilename == NULL) {
		uprintf(conversion_error, token);
		goto out;
	}
	fd = _wfopen(wfilename, L"r, ccs=UNICODE");
	if (fd == NULL) goto out;

	// Process individual lines. NUL is always appended.
	// Ideally, we'd check that our buffer fits the line
	while (fgetws(buf, ARRAYSIZE(buf), fd) != NULL) {
		wdata = get_token_data_line(wtoken, buf);
		if (wdata != NULL) {
			ret = wchar_to_utf8(wdata);
			break;
		}
	}

out:
	if (fd != NULL)
		fclose(fd);
	safe_free(wfilename);
	safe_free(wtoken);
	return ret;
}
Ejemplo n.º 24
0
static void
test_wchar2utf8(const wchar_t *src, size_t slen, const char *dst, size_t dlen,
                int flags, size_t res, const char *descr)
{
    size_t size;
    char *mem;

    mem = NULL;
    if (dst != NULL) {
        mem = (char *)malloc(dlen);
        if (mem == NULL) {
            fprintf(stderr, "w2u: %s: MALLOC FAILED\n", descr);
            return;
        }
    }

    do {
        size = wchar_to_utf8(src, slen, mem, dlen, flags);
        if (res != size) {
            retval = 1;
            fprintf(stderr,
                    "w2u: %s: FAILED (rv: %u, must be %u)\n",
                    descr, size, res);
            break;
        }

        if (mem == NULL)
            break;		/* OK */

        if (memcmp(mem, dst, size) != 0) {
            retval = 1;
            fprintf(stderr, "w2u: %s: BROKEN\n", descr);
            break;
        }

    } while (0);

    if (mem != NULL);
    free(mem);
}
Ejemplo n.º 25
0
DWORD XFile::WriteAsUTF8(CTSTR lpBuffer, DWORD dwElements)
{
    traceInFast(XFile::WriteAsUTF8);

    if(!lpBuffer)
        return 0;

    if(!hFile) return XFILE_ERROR;

    if(!dwElements)
        dwElements = slen(lpBuffer);

    DWORD dwBytes = (DWORD)wchar_to_utf8_len(lpBuffer, dwElements, 0);
    LPSTR lpDest = (LPSTR)Allocate(dwBytes+1);
    wchar_to_utf8(lpBuffer, dwElements, lpDest, dwBytes, 0);
    DWORD retVal = Write(lpDest, dwBytes);
    Free(lpDest);

    return retVal;

    traceOutFast;
}
Ejemplo n.º 26
0
// eng: Returns path to folder with emitters
// rus: Возвращает путь к папке с ptc-файлами
const char* MP_Platform_WIN_POSIX::GetPathToPTC()
{
	if (ptc_path.empty())
	{
		#ifdef _WINDOWS
        
        wchar_t path[MAX_PATH];
        
		#if 0//ndef TEST
		GetModuleFileNameW(NULL, path, MAX_PATH); 
		int len=wcslen(path);
		for (int i=len-1;i>=0;i--)
		{
			if (path[i]=='\\')
			{
				path[i]=0;
				break;
			}
		}
		#else
		GetCurrentDirectoryW(MAX_PATH, path);
		#endif

		ptc_path=wchar_to_utf8(path);
		ptc_path+='\\';

		#else
        
        char path[MAX_PATH];

		getcwd(path, MAX_PATH);
		ptc_path=path;
		ptc_path+='/';
        
        #endif
	}

	return ptc_path.c_str();
}
Ejemplo n.º 27
0
BOOL
SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder,
                         BOOL fCreate)
{
  wchar_t path[MAX_PATH];
  char *path_c;
  BOOL result;

  path[0] = (wchar_t) 0;
  result = SHGetSpecialFolderPath (hwndOwner, path, nFolder, fCreate);
  /* Note: May return false even if succeeds.  */

  path[MAX_PATH - 1] = (wchar_t) 0;
  path_c = wchar_to_utf8 (path);
  if (! path_c)
    return 0;

  strncpy (lpszPath, path_c, MAX_PATH);
  free (path_c);
  lpszPath[MAX_PATH - 1] = '\0';
  return result;
}
Ejemplo n.º 28
0
String::String(CWSTR str)
{
#ifdef UNICODE
    if(!str)
    {
        curLength = 0;
        lpString = NULL;
        return;
    }

    curLength = slen(str);

    if(curLength)
    {
        lpString = (TSTR)Allocate((curLength+1)*sizeof(TCHAR));
        scpy(lpString, str);
    }
    else
        lpString = NULL;
#else
    if(!str)
    {
        curLength = 0;
        lpString = NULL;
        return;
    }

    size_t wideLen = wcslen(str);
    curLength = (UINT)wchar_to_utf8_len(str, wideLen, 0);

    if(curLength)
    {
        lpString = (TSTR)Allocate(curLength+1);
        wchar_to_utf8(str, wideLen+1, lpString, curLength+1, 0);
    }
    else
        lpString = NULL;
#endif
}
Ejemplo n.º 29
0
json_t* json_string_wchar(CTSTR str)
{
    if(!str)
    {
        return NULL;
    }

    size_t wcharLen = slen(str);
    size_t curLength = (UINT)wchar_to_utf8_len(str, wcharLen, 0);

    if(curLength)
    {
        char *out = (char *) malloc((curLength+1));
        wchar_to_utf8(str,wcharLen, out, curLength + 1, 0);
        out[curLength] = 0;
        json_t* ret = json_string(out);
        free(out);
        return ret;
    }
    else
    {
        return NULL;
    }
}
Ejemplo n.º 30
0
// TODO: allow commandline options (v2)
// TODO: remove existing infs for similar devices (v2)
int __cdecl main(int argc_ansi, char** argv_ansi)
{
	DWORD r;
	BOOL b;
	int i, ret, argc = argc_ansi, si=0;
	char** argv = argv_ansi;
	wchar_t **wenv, **wargv;
	char* hardware_id = NULL;
	char* device_id = NULL;
	char* user_sid = NULL;
	char* inf_name = NULL;
	char path[MAX_PATH_LENGTH];
	char destname[MAX_PATH_LENGTH];
	uintptr_t syslog_reader_thid = -1L;

	// Connect to the messaging pipe
	pipe_handle = CreateFileA(INSTALLER_PIPE_NAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
	if (pipe_handle == INVALID_HANDLE_VALUE) {
		// If we can't connect to the pipe, someone is probably trying to run us standalone
		printf("This application can not be run from the command line.\n");
		printf("Please use your initial installer application if you want to install the driver.\n");
		return WDI_ERROR_NOT_SUPPORTED;
	}

	if (init_dlls()) {
		plog("could not init DLLs");
		ret = WDI_ERROR_RESOURCE;
		goto out;
	}

	// Initialize COM for Restore Point disabling
	CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

	// libwdi provides the arguments as UTF-16 => read them and convert to UTF-8
	if (__wgetmainargs != NULL) {
		__wgetmainargs(&argc, &wargv, &wenv, 1, &si);
		argv = calloc(argc, sizeof(char*));
		for (i=0; i<argc; i++) {
			argv[i] = wchar_to_utf8(wargv[i]);
		}
	} else {
		plog("unable to access UTF-16 args - trying ANSI");
	}

	if (argc < 2) {
		printf("usage: %s <inf_name>\n", argv[0]);
		plog("missing inf_name parameter");
	}

	inf_name = argv[1];
	plog("got parameter %s", argv[1]);
	r = GetFullPathNameU(".", MAX_PATH_LENGTH, path, NULL);
	if ((r == 0) || (r > MAX_PATH_LENGTH)) {
		plog("could not retrieve absolute path of working directory");
		ret = WDI_ERROR_ACCESS;
		goto out;
	}
	safe_strcat(path, MAX_PATH_LENGTH, "\\");
	safe_strcat(path, MAX_PATH_LENGTH, inf_name);

	device_id = req_id(IC_GET_DEVICE_ID);
	hardware_id = req_id(IC_GET_HARDWARE_ID);
	// Will be used if we ever need to create a file, as the original user, from this app
	user_sid = req_id(IC_GET_USER_SID);
	ConvertStringSidToSidA(user_sid, &user_psid);

	// Setup the syslog reader thread
	syslog_ready_event = CreateEvent(NULL, TRUE, FALSE, NULL);
	syslog_terminate_event = CreateEvent(NULL, TRUE, FALSE, NULL);
	syslog_reader_thid = _beginthread(syslog_reader_thread, 0, 0);
	if ( (syslog_reader_thid == -1L)
	  || (WaitForSingleObject(syslog_ready_event, 2000) != WAIT_OBJECT_0) )	{
		plog("Unable to create syslog reader thread");
		SetEvent(syslog_terminate_event);
		// NB: if you try to close the syslog reader thread handle, you get a
		// "more recent driver was found" error from UpdateForPnP. Weird...
	}

	// Disable the creation of a restore point
	disable_system_restore(true);

	// Find if the device is plugged in
	send_status(IC_SET_TIMEOUT_INFINITE);
	if (hardware_id != NULL) {
		plog("Installing driver for %s - please wait...", hardware_id);
		b = UpdateDriverForPlugAndPlayDevicesU(NULL, hardware_id, path, INSTALLFLAG_FORCE, NULL);
		send_status(IC_SET_TIMEOUT_DEFAULT);
		if (b == true) {
			// Success
			plog("driver update completed");
			enumerate_device(device_id);
			ret = WDI_SUCCESS;
			goto out;
		}

		ret = process_error(GetLastError(), path);
		if (ret != WDI_SUCCESS) {
			goto out;
		}
	}

	// TODO: try URL for OEMSourceMediaLocation (v2)
	plog("Copying inf file (for the next time device is plugged) - please wait...");
	send_status(IC_SET_TIMEOUT_INFINITE);
	b = SetupCopyOEMInfU(path, NULL, SPOST_PATH, 0, destname, MAX_PATH_LENGTH, NULL, NULL);
	send_status(IC_SET_TIMEOUT_DEFAULT);
	if (b) {
		plog("copied inf to %s", destname);
		ret = WDI_SUCCESS;
		enumerate_device(device_id);
		goto out;
	}

	ret = process_error(GetLastError(), path);
	if (ret != WDI_SUCCESS) {
		goto out;
	}

	// If needed, flag removed devices for reinstallation. see:
	// http://msdn.microsoft.com/en-us/library/aa906206.aspx
	check_removed(hardware_id);

out:
	// Report any error status code and wait for target app to read it
	send_status(IC_INSTALLER_COMPLETED);
	pstat(ret);
	// Restore the system restore point creation original settings
	disable_system_restore(false);
	// TODO: have libwi send an ACK?
	Sleep(1000);
	SetEvent(syslog_terminate_event);
	if (argv != argv_ansi) {
		for (i=0; i<argc; i++) {
			safe_free(argv[i]);
		}
		safe_free(argv);
	}
	CloseHandle(syslog_ready_event);
	CloseHandle(syslog_terminate_event);
	CloseHandle((HANDLE)syslog_reader_thid);
	CloseHandle(pipe_handle);
	return ret;
}