bool loadConfig(){
    wchar_t inipath[MAX_PATH + 1];
    if(!SUCCEEDED(SHGetFolderPath(NULL,CSIDL_COMMON_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, inipath))) return false;
    wchar_t* path = lstrcat(inipath,L"\\HashingPasswordFilter.ini");
    wchar_t buffer[MAX_PATH + 1];
    if (path==NULL)return false;
    configuration.appsAdmin = loadSetting(path,L"appsAdmin",buffer,MAX_PATH + 1);
    configuration.appsDomain = loadSetting(path,L"appsDomain",buffer,MAX_PATH + 1);
    configuration.appsPasswd = loadSetting(path,L"appsPasswd",buffer,MAX_PATH + 1);
    configuration.ldapAdminBindDn = loadSetting(path,L"ldapAdminBindDn",buffer,MAX_PATH + 1);
    configuration.ldapAdminPasswd = loadSetting(path,L"ldapAdminPasswd",buffer,MAX_PATH + 1);
    configuration.ldapSearchBaseDn = loadSetting(path,L"ldapSearchBaseDn",buffer,MAX_PATH + 1);
    configuration.proxyAddress = loadSetting(path,L"proxyAddress",buffer,MAX_PATH + 1);
    configuration.useProxy = lstrcmp(configuration.proxyAddress,L"")==0?false:true;
    if (configuration.useProxy){
        configuration.proxyUser = loadSetting(path,L"proxyUser",buffer,MAX_PATH + 1);
        configuration.proxyPassword = loadSetting(path,L"proxyPassword",buffer,MAX_PATH + 1);
    } else {
        configuration.proxyUser = L"";
        configuration.proxyPassword = L"";
    }
    wchar_t* temp = loadSetting(path,L"processPath",buffer,MAX_PATH + 1);
    int cmdLineLen = _scwprintf(PROCESS_COMMAND_LINE_FORMAT_STRING,temp,PROCESS_COMMAND_LINE_PARAMETERS,
        configuration.proxyAddress, configuration.proxyUser, configuration.proxyPassword) + 1;
    configuration.processCommandLine = (wchar_t*)malloc(cmdLineLen * sizeof(wchar_t));
    swprintf(configuration.processCommandLine,cmdLineLen,PROCESS_COMMAND_LINE_FORMAT_STRING,temp,
        PROCESS_COMMAND_LINE_PARAMETERS, configuration.proxyAddress, configuration.proxyUser,
        configuration.proxyPassword);
    free(temp);
    configuration.processPasswd = loadSetting(path,L"processPasswd",buffer,MAX_PATH + 1);
    configuration.processUser = loadSetting(path,L"processUser",buffer,MAX_PATH + 1);

    return true;
}
示例#2
0
文件: init.c 项目: mantyr/libui
static const char *initerr(const char *message, const WCHAR *label, DWORD value)
{
    WCHAR *sysmsg;
    BOOL hassysmsg;
    WCHAR *beforele;
    WCHAR *afterle;
    int n;
    WCHAR *wmessage;
    WCHAR *wstr;
    const char *str;

    if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, value, 0, (LPWSTR) (&sysmsg), 0, NULL) != 0) {
        hassysmsg = TRUE;
        beforele = L" (";
        afterle = L")";
    } else {
        hassysmsg = FALSE;
        sysmsg = L"";
        beforele = L"";
        afterle = L"";
    }
    wmessage = toUTF16(message);
    n = _scwprintf(initErrorFormat, initErrorArgs);
    wstr = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]");
    snwprintf(wstr, n + 1, initErrorFormat, initErrorArgs);
    str = toUTF8(wstr);
    uiFree(wstr);
    if (hassysmsg)
        if (LocalFree(sysmsg) != NULL)
            logLastError("error freeing system message in loadLastError()");
    uiFree(wmessage);
    return str;
}
示例#3
0
void _DBGPRINT( LPCWSTR kwszFunction, INT iLineNumber, LPCWSTR kwszDebugFormatString, ... )
{
    INT cbFormatString = 0;
    va_list args;
    PWCHAR wszDebugString = NULL;
    size_t st_Offset = 0;

    va_start( args, kwszDebugFormatString );

    cbFormatString = _scwprintf( L"[%s:%d] ", kwszFunction, iLineNumber ) * sizeof( WCHAR );
    cbFormatString += _vscwprintf( kwszDebugFormatString, args ) * sizeof( WCHAR ) + 2;

    /* Depending on the size of the format string, allocate space on the stack or the heap. */
    wszDebugString = (PWCHAR)_malloca( cbFormatString );

    /* Populate the buffer with the contents of the format string. */
    StringCbPrintfW( wszDebugString, cbFormatString, L"[%s:%d] ", kwszFunction, iLineNumber );
    StringCbLengthW( wszDebugString, cbFormatString, &st_Offset );
    StringCbVPrintfW( &wszDebugString[st_Offset / sizeof(WCHAR)], cbFormatString - st_Offset, kwszDebugFormatString, args );

    OutputDebugStringW( wszDebugString );

    _freea( wszDebugString );
    va_end( args );
}
示例#4
0
void BrowserFactory::LaunchBrowserUsingCreateProcess(const std::string& initial_url,
                                                     const std::string& command_line_switches,
                                                     PROCESS_INFORMATION* proc_info,
                                                     std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::LaunchBrowserUsingCreateProcess";
  LOG(DEBUG) << "Starting IE using the CreateProcess API";

  STARTUPINFO start_info;
  ::ZeroMemory(&start_info, sizeof(start_info));
  start_info.cb = sizeof(start_info);

  std::wstring wide_initial_url = StringUtilities::ToWString(initial_url);
  std::wstring wide_ie_switches = StringUtilities::ToWString(command_line_switches);

  std::wstring executable_and_url = this->ie_executable_location_;
  if (wide_ie_switches.size() != 0) {
    executable_and_url.append(L" ");
    executable_and_url.append(wide_ie_switches);
  }
  executable_and_url.append(L" ");
  executable_and_url.append(wide_initial_url);

  LOG(TRACE) << "IE starting command line is: '" << LOGWSTRING(executable_and_url) << "'.";

  LPWSTR command_line = new WCHAR[executable_and_url.size() + 1];
  wcscpy_s(command_line,
           executable_and_url.size() + 1,
           executable_and_url.c_str());
  command_line[executable_and_url.size()] = L'\0';
  BOOL create_process_result = ::CreateProcess(NULL,
                                               command_line,
                                               NULL,
                                               NULL,
                                               FALSE,
                                               0,
                                               NULL,
                                               NULL,
                                               &start_info,
                                               proc_info);
  if (!create_process_result) {
    int create_proc_msg_count = _scwprintf(CREATEPROCESS_ERROR_MESSAGE,
                                           command_line);
    vector<wchar_t> create_proc_result_msg(create_proc_msg_count + 1);
    _snwprintf_s(&create_proc_result_msg[0],
                  create_proc_result_msg.size(),
                  create_proc_msg_count,
                  CREATEPROCESS_ERROR_MESSAGE,
                  command_line);
    std::string launch_error = StringUtilities::ToString(&create_proc_result_msg[0]);
    *error_message = launch_error;
  }
  delete[] command_line;
}
示例#5
0
DWORD BrowserFactory::LaunchBrowserProcess(const std::string& initial_url,
                                           const bool ignore_protected_mode_settings,
                                           std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::LaunchBrowserProcess";

  DWORD process_id = NULL;
  bool has_valid_protected_mode_settings = false;
  LOG(DEBUG) << "Ignoring Protected Mode Settings: "
             << ignore_protected_mode_settings;
  if (!ignore_protected_mode_settings) {
    LOG(DEBUG) << "Checking validity of Protected Mode settings.";
    has_valid_protected_mode_settings = this->ProtectedModeSettingsAreValid();
  }
  LOG(DEBUG) << "Has Valid Protected Mode Settings: "
             << has_valid_protected_mode_settings;
  if (ignore_protected_mode_settings || has_valid_protected_mode_settings) {
    STARTUPINFO start_info;
    PROCESS_INFORMATION proc_info;

    ::ZeroMemory(&start_info, sizeof(start_info));
    start_info.cb = sizeof(start_info);
    ::ZeroMemory(&proc_info, sizeof(proc_info));

    std::wstring wide_initial_url(CA2W(initial_url.c_str(), CP_UTF8));

    FARPROC proc_address = 0;
    HMODULE library_handle = ::LoadLibrary(IEFRAME_LIBRARY_NAME);
    if (library_handle != NULL) {
      proc_address = ::GetProcAddress(library_handle, IELAUNCHURL_FUNCTION_NAME);
    }

    std::string launch_api = "The IELaunchURL() API";
    std::string launch_error = "";
    if (proc_address != 0) {
      // If we have the IELaunchURL API, expressly use it. This will
      // guarantee a new session. Simply using CoCreateInstance to 
      // create the browser will merge sessions, making separate cookie
      // handling impossible.
      HRESULT launch_result = ::IELaunchURL(wide_initial_url.c_str(),
                                            &proc_info,
                                            NULL);
      if (FAILED(launch_result)) {
        size_t launch_msg_count = _scprintf(IELAUNCHURL_ERROR_MESSAGE,
                                            launch_result,
                                            initial_url);
        vector<char> launch_result_msg(launch_msg_count + 1);
        _snprintf_s(&launch_result_msg[0],
                    sizeof(launch_result_msg),
                    launch_msg_count + 1,
                    IELAUNCHURL_ERROR_MESSAGE,
                    launch_result,
                    initial_url);
        launch_error = &launch_result_msg[0];
        *error_message = launch_error;
      }
    } else {
      launch_api = "The CreateProcess() API";
      std::wstring executable_and_url = this->ie_executable_location_ +
                                        L" " + wide_initial_url;
      LPWSTR command_line = new WCHAR[executable_and_url.size() + 1];
      wcscpy_s(command_line,
               executable_and_url.size() + 1,
               executable_and_url.c_str());
      command_line[executable_and_url.size()] = L'\0';
      BOOL create_process_result = ::CreateProcess(NULL,
                                                   command_line,
                                                   NULL,
                                                   NULL,
                                                   FALSE,
                                                   0,
                                                   NULL,
                                                   NULL,
                                                   &start_info,
                                                   &proc_info);
      if (!create_process_result) {
        int create_proc_msg_count = _scwprintf(CREATEPROCESS_ERROR_MESSAGE,
                                               command_line);
        vector<wchar_t> create_proc_result_msg(create_proc_msg_count + 1);
        _snwprintf_s(&create_proc_result_msg[0],
                     sizeof(create_proc_result_msg),
                     create_proc_msg_count,
                     CREATEPROCESS_ERROR_MESSAGE,
                     command_line);
        launch_error = CW2A(&create_proc_result_msg[0], CP_UTF8);
        *error_message = launch_error;
      }
      delete[] command_line;
    }

    process_id = proc_info.dwProcessId;
    if (process_id == NULL) {
      // If whatever API we are using failed to launch the browser, we should
      // have a NULL value in the dwProcessId member of the PROCESS_INFORMATION
      // structure. In that case, we will have already set the approprate error
      // message. On the off chance that we haven't yet set the appropriate
      // error message, that means we successfully launched the browser (i.e.,
      // the browser launch API returned a success code), but we still have a
      // NULL process ID.
      if (launch_error.size() == 0) {
        *error_message = launch_api + NULL_PROCESS_ID_ERROR_MESSAGE;
      }
    }

    if (proc_info.hThread != NULL) {
      ::CloseHandle(proc_info.hThread);
    }

    if (proc_info.hProcess != NULL) {
      ::CloseHandle(proc_info.hProcess);
    }

    if (library_handle != NULL) {
      ::FreeLibrary(library_handle);
    }
  } else {
    *error_message = PROTECTED_MODE_SETTING_ERROR_MESSAGE;
  }
  return process_id;
}
示例#6
0
文件: mimerun.c 项目: LRN/mimerun
/* Enumerates the subkeys of <hKey>/Software/mimerun/rules and looks for a rule that matches the values
 * from <mres>, <lpfile> and <einfo>->lpParameters
 * Once a matching rule is found, its handler is executed and the function returns without looking checking
 * any other rules.
 */
int handle_key (wchar_t *logfile, HKEY hKey, MimeResults *mres, LPSHELLEXECUTEINFOW einfo, wchar_t *lpfile, wchar_t *lpdir)
{
  wchar_t *handle_val = NULL;
  HKEY rules;
  wchar_t *matchstring = NULL;
  wchar_t **allkeys = NULL;
  wchar_t *handler = NULL;
  DWORD allkeys_len, maxkey_len;
  LONG res = 0;
  int ret = -4;
  DWORD matchlen = 0;
  DWORD i;
  DWORD len = 0;
  BOOL sorted;

  logtofilew (logfile, L">handle_key\n");

  matchlen = _scwprintf (MATCHSTRING_FORMAT_ARGS(mres, einfo, lpfile));
  if (matchlen <= 0)
  {
    logtofilew (logfile, L"match string length %d <= 0\n", matchlen);
    ret = -1;
    goto end;
  }
  res = RegOpenKeyExW (hKey, L"Software\\mimerun\\rules", 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_32KEY, &rules);
  if (res != ERROR_SUCCESS)
  {
    logtofilew (logfile, L"Failed to open %08X\\Software\\mimerun\\rules\n", hKey);
    ret = -2;
    goto end;
  }
  res = RegQueryInfoKeyW (rules, NULL, NULL, NULL, &allkeys_len, &maxkey_len, NULL, NULL, NULL, NULL, NULL, NULL);
  if (res != ERROR_SUCCESS || (allkeys_len <= 0 || maxkey_len <= 0))
  {
    logtofilew (logfile, L"Failed to query keys from %08X\\Software\\mimerun\\rules\n", hKey);
    ret = -3;
    goto end;
  }
  allkeys = (wchar_t **) malloc (sizeof (wchar_t *) * (allkeys_len + 1));
  if (allkeys == NULL)
  {
    logtofilew (logfile, L"Failed to allocate %d bytes for rule keys\n", sizeof (wchar_t *) * (allkeys_len + 1));
    ret = -4;
    goto end;
  }
  memset (allkeys, 0, sizeof (wchar_t *) * (allkeys_len + 1));
  for (i = 0; i < allkeys_len; i++)
  {
    allkeys[i] = (wchar_t *) malloc (sizeof (wchar_t) * (maxkey_len + 1));
    if (allkeys[i] == NULL)
    {
      logtofilew (logfile, L"Failed to allocate %d bytes for one of the rule keys\n", sizeof (wchar_t) * (maxkey_len + 1));
      ret = -5;
      goto end;
    }
  }
  allkeys[allkeys_len] = NULL;
  for (i = 0; res == ERROR_SUCCESS; i++)
  {
    len = maxkey_len + 1;
    res = RegEnumKeyExW (rules, i, allkeys[i], &len, NULL, NULL, NULL, NULL);
  }
  logtofilew (logfile, L"Enumerated %d rules\n", i - 1);
  sorted = FALSE;
  while (!sorted)
  {
    sorted = TRUE;
    for (i = 1; i < allkeys_len; i++)
    {
      if (wcscmp (allkeys[i - 1], allkeys[i]) > 0)
      {
        sorted = FALSE;
        wchar_t *tmp;
        tmp = allkeys[i - 1];
        allkeys[i - 1] = allkeys[i];
        allkeys[i] = tmp;
      }
    }
  }
  matchstring = (wchar_t *) malloc (sizeof (wchar_t) * (matchlen + 1));
  swprintf (matchstring, MATCHSTRING_FORMAT_ARGS(mres, einfo, lpfile));
  logtofilew (logfile, L"Matchstring: %s\n", matchstring);
  for (i = 0; i < allkeys_len; i++)
  {
    if ((ret = match_rule (logfile, rules, allkeys[i], matchstring)) == 0)
    {
      handler = NULL;
      DWORD executable = 0;
      DWORD fix_redir = 0;
      DWORD shebang_flags = 0;
      char shebang_interp[MAX_PATH + 1];
      char *shebang_args = NULL;
      if (get_dword_key (rules, allkeys[i], L"executable", &executable, KEY_WOW64_32KEY) != 0)
        executable = 1;
      if (get_dword_key (rules, allkeys[i], L"fix_wow64_redirection", &fix_redir, KEY_WOW64_32KEY) != 0)
        fix_redir = 0;
      if (get_dword_key (rules, allkeys[i], L"shebang", &shebang_flags, KEY_WOW64_32KEY) != 0)
        shebang_flags = 0;
      logtofilew (logfile, L"Found a handler, execuable is %d, fix_wow64_redirection is %d, shebang is %d\n", executable, fix_redir, shebang_flags);

      if (shebang_flags & MIMERUN_SHEBANG_LOOKFORIT)
      {
        logtofilew (logfile, L"Trying to get shebang... ");
        if (get_shebang (lpfile, shebang_interp, &shebang_args) < 0)
        {
          shebang_flags = 0;
          logtofilew (logfile, L"FAILURE\n");
        }
        else
        {
          logtofilew (logfile, L"%S %S\n", shebang_interp, shebang_args ? shebang_args : "");
        }
      }
      if (shebang_flags & MIMERUN_SHEBANG_LOOKFORIT && shebang_flags & MIMERUN_SHEBANG_TRYITFIRST)
      {
        wchar_t *tmp = dup_wprintf (NULL, L"%S%s%S %s", shebang_interp, shebang_args == NULL ? L"" : L" ", shebang_args == NULL ? "" : shebang_args, lpfile);
        if (tmp != NULL)
        {
          ret = run_handler (logfile, tmp, mres, einfo, lpfile, lpdir, 1, fix_redir);
          free (tmp);
          free (shebang_args);
          if (shebang_flags & MIMERUN_SHEBANG_BAILONIT || ret == 0)
          {
            logtofilew (logfile, L"Bailing out after shebang\n", ret);
            goto end;
          }
          else
            einfo->hInstApp = (HINSTANCE) 33;
        }
      }
      if (get_sz_key (rules, allkeys[i], L"handler", &handler, KEY_WOW64_32KEY) == 0 && handler != NULL)
      {
        ret = run_handler (logfile, handler, mres, einfo, lpfile, lpdir, executable, fix_redir);
        free (handler);
        handler = NULL;
        if (ret == 0)
        {
          logtofilew (logfile, L"Handled, returning\n");
          goto end;
        }
      }
      else
      {
        logtofilew (logfile, L"Failed to get handler value\n");
      }
      if (shebang_flags & MIMERUN_SHEBANG_LOOKFORIT && ~shebang_flags & MIMERUN_SHEBANG_TRYITFIRST)
      {
        wchar_t *tmp = dup_wprintf (NULL, L"%S%s%S %s", shebang_interp, shebang_args == NULL ? L"" : L" ", shebang_args == NULL ? "" : shebang_args, lpfile);
        if (tmp != NULL)
        {
          ret = run_handler (logfile, tmp, mres, einfo, lpfile, lpdir, 1, fix_redir);
          free (tmp);
          free (shebang_args);
          if (shebang_flags & MIMERUN_SHEBANG_BAILONIT || ret == 0)
          {
            logtofilew (logfile, L"Bailing out after shebang\n");
            goto end;
          }
        }
      }
      ret = -4;
    }
  }
end:
  logtofilew (logfile, L"Cleaning up handle_key\n");
  if (matchstring != NULL)
    free (matchstring);
  if (allkeys != NULL)
  {
    for (i = 0; allkeys[i] != NULL; i++)
      free (allkeys[i]);
    free (allkeys);
  }
  if (rules != NULL)
    RegCloseKey (rules);

  logtofilew (logfile, L"<handle_key %d\n", ret);
  return ret;
}
示例#7
0
void convert_values( extended_info **ei )
{
	extended_info *l_ei = *ei;
	column_info *t_ci = g_ci;

	int buf_count = 0;

	wchar_t *format = NULL;

	for ( unsigned long i = 0; i < g_column_count; ++i )
	{
		// Stop processing and exit the thread.
		if ( g_kill_scan == true )
		{
			break;
		}

		if ( t_ci != NULL )
		{
			// Create a shared extended info structure to share the Windows Property names across entries.
			if ( t_ci->sei == NULL )
			{
				t_ci->sei = ( shared_extended_info * )malloc( sizeof( shared_extended_info ) );
				t_ci->sei->count = 0;

				t_ci->sei->windows_property = ( wchar_t * )malloc( sizeof( char ) * ( t_ci->Name_byte_length + sizeof( wchar_t ) ) );
				memcpy_s( t_ci->sei->windows_property, sizeof( char ) * ( t_ci->Name_byte_length + sizeof( wchar_t ) ), t_ci->Name, t_ci->Name_byte_length );

				t_ci->sei->windows_property[ t_ci->Name_byte_length / sizeof( wchar_t ) ] = 0;	// Sanity.
			}

			++( t_ci->sei->count );

			extended_info *t_ei = ( extended_info * )malloc( sizeof( extended_info ) );
			t_ei->sei = t_ci->sei;
			t_ei->property_value = NULL;
			t_ei->next = NULL;

			// See if the property value was retrieved.
			if ( g_rc_array[ i ].cbActual != 0 && g_rc_array[ i ].cbActual <= t_ci->max_size )
			{
				switch ( t_ci->column_type )
				{
					case JET_coltypBit:
					{
						// Handles Type(s): VT_BOOL

						if ( t_ci->Type == VT_BOOL )	// bool (true == -1, false == 0)
						{
							buf_count = ( t_ci->data[ 0 ] != 0 ? 4 : 5 );	// "true" or "false"
							t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 1 ) );
							wcscpy_s( t_ei->property_value, buf_count + 1, ( t_ci->data[ 0 ] != 0 ? L"true" : L"false" ) );

							break;
						}

						// For anything else, fall through to JET_coltypUnsignedByte
					}

					case JET_coltypUnsignedByte:
					{
						// Handles Type(s): VT_I1, VT_UI1, anything else from JET_coltypBit

						format = ( t_ci->Type == VT_I1 ? L"%d" : L"%lu" );
						buf_count = _scwprintf( format, t_ci->data[ 0 ] );
						if ( buf_count > 0 )
						{
							t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 1 ) );
							swprintf_s( t_ei->property_value, buf_count + 1, format, t_ci->data[ 0 ] );
						}
					}
					break;

					case JET_coltypShort:
					case JET_coltypUnsignedShort:
					{
						// Handles Type(s): VT_UI2

						unsigned short val = 0;
						memcpy_s( &val, sizeof( unsigned short ), t_ci->data, sizeof( unsigned short ) );

						format = ( t_ci->column_type == JET_coltypShort ? L"%d" : L"%lu" );
						buf_count = _scwprintf( format, val );
						if ( buf_count > 0 )
						{
							t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 1 ) );
							swprintf_s( t_ei->property_value, buf_count + 1, format, val );
						}
					}
					break;

					case JET_coltypLong:
					case JET_coltypUnsignedLong:
					{
						// Handles Type(s): VT_I4, VT_UI4

						unsigned long val = 0;
						memcpy_s( &val, sizeof( unsigned long ), t_ci->data, sizeof( unsigned long ) );

						if ( t_ci->Name_byte_length == 42 && wcscmp( t_ci->Name, L"System_FileAttributes" ) == 0 )
						{
							t_ei->property_value = get_file_attributes( val );
						}
						else if ( ( t_ci->Name_byte_length == 34 && wcscmp( t_ci->Name, L"System_SFGAOFlags" ) == 0 ) ||
								  ( t_ci->Name_byte_length == 56 && wcscmp( t_ci->Name, L"System_Link_TargetSFGAOFlags" ) == 0 ) )
						{
							t_ei->property_value = get_sfgao( val );
						}
						else
						{
							format = ( t_ci->column_type == JET_coltypLong ? L"%d" : L"%lu" );
							buf_count = _scwprintf( format, val );
							if ( buf_count > 0 )
							{
								t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 1 ) );
								swprintf_s( t_ei->property_value, buf_count + 1, format, val );
							}
						}
					}
					break;

					case JET_coltypIEEEDouble:
					{
						// Handles Type(s): VT_R8

						double val = 0.0f;
						memcpy_s( &val, sizeof( double ), t_ci->data, sizeof( double ) );

						buf_count = _scwprintf( L"%f", val );
						if ( buf_count > 0 )
						{
							t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 1 ) );
							swprintf_s( t_ei->property_value, buf_count + 1, L"%f", val );
						}
					}
					break;

					case JET_coltypCurrency:
					case JET_coltypBinary:		// May be compressed. We'll fall through to JET_coltypLongBinary to handle uncompressing it.
					case JET_coltypLongLong:
					{
						// Handles Type(s): VT_FILETIME, VT_UI8, VT_LPWSTR

						unsigned long long val = 0;
						memcpy_s( &val, sizeof( unsigned long long ), t_ci->data, sizeof( unsigned long long ) );

						if ( g_use_big_endian == true )
						{
							val = ntohll( val );
						}

						if ( t_ci->Type == VT_FILETIME )	// FILETIME
						{
							SYSTEMTIME st;
							FILETIME ft;
							ft.dwLowDateTime = ( DWORD )val;
							ft.dwHighDateTime = ( DWORD )( val >> 32 );
							FileTimeToSystemTime( &ft, &st );

							buf_count = _scwprintf( L"%d/%d/%d (%02d:%02d:%02d.%d) [UTC]", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds );
							if ( buf_count > 0 )
							{
								t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 1 ) );
								swprintf_s( t_ei->property_value, buf_count + 1, L"%d/%d/%d (%02d:%02d:%02d.%d) [UTC]", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds );
							}

							break;
						}
						else
						{
							if ( t_ci->Name_byte_length == 22 && wcscmp( t_ci->Name, L"System_Size" ) == 0 )
							{
								buf_count = _scwprintf( L"%llu", val );
								if ( buf_count > 0 )
								{
									t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 6 + 1 ) );
									swprintf_s( t_ei->property_value, buf_count + 6 + 1, L"%llu bytes", val );
								}

								break;
							}
							else if ( t_ci->Name_byte_length == 46 && wcscmp( t_ci->Name, L"System_ThumbnailCacheId" ) == 0 )
							{
								t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * 17 );
								swprintf_s( t_ei->property_value, 17, L"%016llx", val );

								break;
							}
							else if ( t_ci->Name_byte_length == 30 && wcscmp( t_ci->Name, L"InvertedOnlyMD5" ) == 0 )
							{
								// Output hex values.
								unsigned long property_value_offset = 0;
								buf_count = ( ( g_rc_array[ i ].cbActual * 2 ) + 1 );
								t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * buf_count );
								for ( unsigned long h = 0; h < g_rc_array[ i ].cbActual; ++h )
								{
									property_value_offset += swprintf_s( t_ei->property_value + property_value_offset, buf_count - property_value_offset, L"%02x", t_ci->data[ h ] );
								}

								break;
							}
							else
							{
								if ( t_ci->JetCompress == false )
								{
									// Handle 8 byte values. For everything else, fall through.
									if ( g_rc_array[ i ].cbActual == sizeof( unsigned long long ) )
									{
										format = ( t_ci->column_type == JET_coltypLongLong ? L"%lld" : L"%llu" );
										buf_count = _scwprintf( format, val );
										if ( buf_count > 0 )
										{
											t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * ( buf_count + 1 ) );
											swprintf_s( t_ei->property_value, buf_count + 1, format, val );
										}

										break;
									}
								}

								// Fall through to JET_coltypLongBinary.
							}
						}
					}

					case JET_coltypText:
					case JET_coltypLongBinary:
					case JET_coltypLongText:
					case JET_coltypGUID:
					{
						// Handles Type(s): VT_NULL, VT_LPWSTR, ( VT_VECTOR | VT_LPWSTR ), VT_BLOB, anything else from JET_coltypBinary

						if ( t_ci->column_type == JET_coltypGUID )
						{
							if ( g_rc_array[ i ].cbActual == 16 )
							{
								// Output GUID formatted value.
								unsigned long val_1 = 0;
								unsigned short val_2 = 0, val_3 = 0;

								memcpy_s( &val_1, sizeof( unsigned long ), t_ci->data, sizeof( unsigned long ) );
								memcpy_s( &val_2, sizeof( unsigned short ), t_ci->data + sizeof( unsigned long ), sizeof( unsigned short ) );
								memcpy_s( &val_3, sizeof( unsigned short ), t_ci->data + sizeof( unsigned long ) + sizeof( unsigned short ), sizeof( unsigned short ) );

								buf_count = ( ( g_rc_array[ i ].cbActual * 2 ) + 6 + 1 );
								t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * buf_count );

								unsigned long property_value_offset = swprintf_s( t_ei->property_value, buf_count, L"{%04x-%02x-%02x-", val_1, val_2, val_3 );
								for ( unsigned long h = sizeof( unsigned long ) + ( sizeof( unsigned short ) * 2 ); h < g_rc_array[ i ].cbActual; ++h )
								{
									if ( h == 10 )
									{
										t_ei->property_value[ property_value_offset ] = L'-';
										++property_value_offset;
									}
									property_value_offset += swprintf_s( t_ei->property_value + property_value_offset, buf_count - property_value_offset, L"%02x", t_ci->data[ h ] );
								}
								t_ei->property_value[ buf_count - 2 ] = L'}';
								t_ei->property_value[ buf_count - 1 ] = 0;	// Sanity.

								break;
							}

							// Fall through to default.
						}
						else
						{
							// On Vista, if Type == ( VT_VECTOR | VT_LPWSTR ), then the first 2 bytes (little-endian) = array count?
							if ( t_ci->JetCompress == true )
							{
								// Make a copy first because we may need to reuse t_ci->data and don't want it modified.
								unsigned char *data_copy = ( unsigned char * )malloc( sizeof( unsigned char ) * g_rc_array[ i ].cbActual );
								memcpy_s( data_copy, sizeof( unsigned char ) * g_rc_array[ i ].cbActual, t_ci->data, g_rc_array[ i ].cbActual );

								t_ei->property_value = uncompress_value( data_copy, g_rc_array[ i ].cbActual );

								free( data_copy );

								break;
							}
							else
							{
								if ( t_ci->Name_byte_length == 32 && wcscmp( t_ci->Name, L"InvertedOnlyPids" ) == 0 )
								{
									// Output hex values.
									unsigned long property_value_offset = 0;
									buf_count = ( ( g_rc_array[ i ].cbActual * 2 ) + 1 );
									t_ei->property_value = ( wchar_t * )malloc( sizeof( wchar_t ) * buf_count );
									for ( unsigned long h = 0; h < g_rc_array[ i ].cbActual; ++h )
									{
										property_value_offset += swprintf_s( t_ei->property_value + property_value_offset, buf_count - property_value_offset, L"%02x", t_ci->data[ h ] );
									}

									break;
								}

								// Fall through to default.
							}
						}
					}

					default:
					{
						// This is usually wchar strings.

						t_ei->property_value = ( wchar_t * )malloc( sizeof( char ) * ( g_rc_array[ i ].cbActual + sizeof( wchar_t ) ) );	// Include the NULL terminator.
						memcpy_s( t_ei->property_value, sizeof( char ) * ( g_rc_array[ i ].cbActual + sizeof( wchar_t ) ), t_ci->data, g_rc_array[ i ].cbActual );

						unsigned long property_value_size = g_rc_array[ i ].cbActual / sizeof( wchar_t );
						t_ei->property_value[ property_value_size ] = 0;	// Sanity.

						// See if we have any string arrays.
						if ( wcslen( t_ei->property_value ) < property_value_size )
						{
							// Replace the NULL character at the end of each string (except the last) with a ';' separator.
							wchar_t *t_val = t_ei->property_value;
							while ( t_val < ( t_ei->property_value + property_value_size ) )
							{
								if ( *t_val == 0 )
								{
									*t_val = L';';
								}

								++t_val;
							}
						}
					}
					break;
				}
			}

			if ( l_ei != NULL )
			{
				l_ei->next = t_ei;
			}
			else
			{
				*ei = t_ei;
			}

			l_ei = t_ei;

			// Go to the next Windows property.
			t_ci = t_ci->next;
		}