void FacadeDocumentProviderImpl::Configure()
{
	wchar_t fileName[_MAX_PATH] = {0};
	if(0 >= ::GetModuleFileNameW(NULL, fileName, _MAX_PATH))
		throw Workshare::System::SystemException(_T("Failed to get the filename of the running executable"));

	PathRemoveExtensionW(fileName);
	PathStripPathW(fileName);

	DialogStyle style = dsTab;
	if(0 == lstrcmpiW(fileName, L"winword"))
	{
		style = dsWizard;	
	}
	else if(0 == lstrcmpiW(fileName, L"WmConfigAssistant"))	
	{
		style = dsWcaWizard;	
	}
	else if(0 == lstrcmpiW(fileName, L"WmConfigPixie"))
	{
		style = dsWcaWizard;	
	}
	else if(0 == lstrcmpiW(fileName, L"Msiexec"))
	{
		style = dsWcaWizard;
	}

	ConnectorManager::Configure(GetConnector(), style);
}
Exemple #2
0
/*************************************************************************
 * PathStripPath	[SHELL32.38]
 */
void WINAPI PathStripPathAW(LPVOID lpszPath)
{
	if (SHELL_OsIsUnicode())
            PathStripPathW(lpszPath);
        else
            PathStripPathA(lpszPath);
}
Exemple #3
0
	bool CLoggingImp::InitLogging()
	{
		if (!SHGetSpecialFolderPathW(0, m_wszLogDir, CSIDL_APPDATA, TRUE))
		{
			return false;
		}
		PathAppendW(m_wszLogDir, L"Logging");
		if (!CreateDirectoryW(m_wszLogDir, 0) && 
			GetLastError() != ERROR_ALREADY_EXISTS)
		{
			return false;
		}

		CleanOldLog();

		wchar_t wszBaseName[MAX_PATH] = {0};
		if (!GetModuleFileNameW(0, wszBaseName, MAX_PATH))
		{
			return false;
		}
		PathRemoveExtensionW(wszBaseName);
		PathStripPathW(wszBaseName);
		wchar_t wszLogFile[MAX_PATH] = {0};
		HRESULT hr = StringCchPrintfW(wszLogFile, MAX_PATH, L"%s\\%s_PID%d_%d.log", 
			m_wszLogDir, wszBaseName, GetCurrentProcessId(), GetTickCount());
		if (FAILED(hr))
		{
			return false;
		}
		//create file
		std::locale loc("");
		m_logwfstream.imbue(loc);
		m_logwfstream.open(wszLogFile, std::ios_base::out);	//TODO: what mode?
		if (!m_logwfstream)
		{
			return false;
		}
		//initialize critical section
		bool bOk = true;
		try
		{
			InitializeCriticalSection(&m_csWriteFile);
		}
		catch (...)
		{
			bOk = false;
			m_logwfstream.close();
		}
		
		m_logwfstream << L"\t\tIF ANY ERROR OCCURRED, "
			L"PLS CONTACT ME: [email protected].\n\n\n";
		
		return bOk;
	}
Exemple #4
0
BOOL CheckInstaller()
{
	WCHAR PathBuffer[512];
	DWORD Result;

	Result = GetModuleFileNameW(NULL, PathBuffer, sizeof(PathBuffer));
	if (Result)
	{
		PathStripPathW(PathBuffer);
		wcslwr(PathBuffer);

		if ((wcscmp(L"msiexec.exe", PathBuffer) == 0) ||
			(wcscmp(L"regsvr32.exe", PathBuffer) == 0))
			return TRUE;
	}

	return FALSE;
}
Exemple #5
0
VOID LoadSatellites(PWCHAR Satellites, HANDLE hModuleToPatch, char* szExportName)
{
	PWCHAR CurrSatellite = Satellites;
	NTSTATUS ntStatus;

	while (CurrSatellite[0] != 0)
	{
		WCHAR WinDir[MAX_PATH];
		WCHAR SysDir[MAX_PATH];
		WCHAR Path[MAX_PATH*4];
		WCHAR Name[MAX_PATH];
		UNICODE_STRING SatelliteName;
		HANDLE hModule;
		DWORD CurrSatellite_PathLen = (DWORD)wcslen(CurrSatellite);
		WCHAR ExeName[MAX_PATH];

// prepare parameters
		memcpy(Path, CurrSatellite, sizeof(WCHAR)*(CurrSatellite_PathLen+1));
		PathRemoveFileSpecW(Path);
		if (GetWindowsDirectoryW(WinDir, _countof(WinDir)))
		{
			wcscat(Path, L";");
			wcscat(Path, WinDir);
		}
		if (GetSystemDirectoryW(SysDir, _countof(SysDir)))
		{
			wcscat(Path, L";");
			wcscat(Path, SysDir);
		}

		memcpy(Name, CurrSatellite, sizeof(WCHAR)*(CurrSatellite_PathLen+1));
		PathStripPathW(Name);

		SatelliteName.Length = (USHORT)wcslen(Name)*sizeof(WCHAR);
		SatelliteName.MaximumLength = (USHORT)(SatelliteName.Length+sizeof(WCHAR));
		SatelliteName.Buffer = Name;

// call original LdrLoadDll
		ntStatus = ((fLdrLoadDll)g_pLdrLoadDll_Context->m_Thunk)(Path, 0, &SatelliteName, &hModule);

		ExeName[0] = 0;
		GetModuleFileNameW(NULL, ExeName, _countof(ExeName));
		PathStripPathW(ExeName);
		DbPrint("r3hook::LoadSatellites - %hs \'%ls\' module into process \'%ls\', search path \'%ls\'\n",
			ntStatus == 0 ? "successefully loaded(or it was already loaded)" : "failed to load",
			Name, ExeName, Path);

		if (ntStatus == 0L && hModule)
		{
			if (szExportName)
			{
				t_fHookHandlerExport f_HookExport;

				DbPrint("r3hook::LoadSatellites - trying to call %hs...\n", szExportName);
				f_HookExport = (t_fHookHandlerExport)GetProcAddress(hModule, szExportName);
				if (f_HookExport)
				{
					//DbPrint("r3hook::LoadSatellites - calling HookExports\n");
					f_HookExport(hModuleToPatch);
				}
				else
					DbPrint("r3hook::LoadSatellites - export '%hs' not found in module %ls\n", szExportName, Name);
			}
		}

		CurrSatellite += CurrSatellite_PathLen+1;
	}
}
Exemple #6
0
/*
    010509 Carl Corcoran
*/
void CCString::Path_StripToFilename()
{
    PathStripPathW(this->wszString);
}
Exemple #7
0
/**************************************************************************
 *  IQueryAssociations_GetString {SHLWAPI}
 *
 * Get a file association string from the registry.
 *
 * PARAMS
 *  iface    [I]   IQueryAssociations interface to query
 *  cfFlags  [I]   ASSOCF_ flags from "shlwapi.h"
 *  str      [I]   Type of string to get (ASSOCSTR enum from "shlwapi.h")
 *  pszExtra [I]   Extra information about the string location
 *  pszOut   [O]   Destination for the association string
 *  pcchOut  [I/O] Length of pszOut
 *
 * RETURNS
 *  Success: S_OK. pszOut contains the string, pcchOut contains its length.
 *  Failure: An HRESULT error code indicating the error.
 */
static HRESULT WINAPI IQueryAssociations_fnGetString(
  IQueryAssociations *iface,
  ASSOCF cfFlags,
  ASSOCSTR str,
  LPCWSTR pszExtra,
  LPWSTR pszOut,
  DWORD *pcchOut)
{
  IQueryAssociationsImpl *This = (IQueryAssociationsImpl *)iface;
  const ASSOCF cfUnimplemented = ~(0);
  DWORD len = 0;
  HRESULT hr;
  WCHAR path[MAX_PATH];

  TRACE("(%p,0x%8x,0x%8x,%s,%p,%p)\n", This, cfFlags, str,
        debugstr_w(pszExtra), pszOut, pcchOut);

  if (cfFlags & cfUnimplemented)
    FIXME("%08x: unimplemented flags!\n", cfFlags & cfUnimplemented);

  if (!pcchOut)
    return E_UNEXPECTED;

  switch (str)
  {
    case ASSOCSTR_EXECUTABLE:
    {
      hr = ASSOC_GetExecutable(This, pszExtra, path, MAX_PATH, &len);
      if (FAILED(hr))
        return hr;
      len++;
      return ASSOC_ReturnData(pszOut, pcchOut, path, len);
    }

    case ASSOCSTR_FRIENDLYAPPNAME:
    {
      PVOID verinfoW = NULL;
      DWORD size, retval = 0;
      UINT flen;
      WCHAR *bufW;
      static const WCHAR translationW[] = {
        '\\','V','a','r','F','i','l','e','I','n','f','o',
        '\\','T','r','a','n','s','l','a','t','i','o','n',0
      };
      static const WCHAR fileDescFmtW[] = {
        '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
        '\\','%','0','4','x','%','0','4','x',
        '\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0
      };
      WCHAR fileDescW[41];

      hr = ASSOC_GetExecutable(This, pszExtra, path, MAX_PATH, &len);
      if (FAILED(hr))
        return hr;

      retval = GetFileVersionInfoSizeW(path, &size);
      if (!retval)
        goto get_friendly_name_fail;
      verinfoW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, retval);
      if (!verinfoW)
        return E_OUTOFMEMORY;
      if (!GetFileVersionInfoW(path, 0, retval, verinfoW))
        goto get_friendly_name_fail;
      if (VerQueryValueW(verinfoW, translationW, (LPVOID *)&bufW, &flen))
      {
        UINT i;
        DWORD *langCodeDesc = (DWORD *)bufW;
        for (i = 0; i < flen / sizeof(DWORD); i++)
        {
          sprintfW(fileDescW, fileDescFmtW, LOWORD(langCodeDesc[i]),
                   HIWORD(langCodeDesc[i]));
          if (VerQueryValueW(verinfoW, fileDescW, (LPVOID *)&bufW, &flen))
          {
            /* Does strlenW(bufW) == 0 mean we use the filename? */
            len = strlenW(bufW) + 1;
            TRACE("found FileDescription: %s\n", debugstr_w(bufW));
            return ASSOC_ReturnData(pszOut, pcchOut, bufW, len);
          }
        }
      }
get_friendly_name_fail:
      PathRemoveExtensionW(path);
      PathStripPathW(path);
      TRACE("using filename: %s\n", debugstr_w(path));
      return ASSOC_ReturnData(pszOut, pcchOut, path, strlenW(path) + 1);
    }

    default:
      FIXME("assocstr %d unimplemented!\n", str);
      return E_NOTIMPL;
  }
}
Exemple #8
0
QList<DWORD> * getDxProcessesIDs(QList<DWORD> * processes, LPCWSTR wstrSystemRootPath) {

    DWORD aProcesses[1024];
    HMODULE hMods[1024];
    DWORD cbNeeded;
    DWORD cProcesses;
    char debug_buf[255];
    WCHAR executableName[MAX_PATH];
    unsigned int i;

    //     Get the list of process identifiers.
    processes->clear();

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return NULL;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the names of the modules for each process.

    for ( i = 0; i < cProcesses; i++ )
    {
        if (aProcesses[i] != GetCurrentProcessId()) {
            HANDLE hProcess;
            hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ,
                                    FALSE, aProcesses[i] );
            if (NULL == hProcess)
                goto nextProcess;

            GetModuleFileNameExW(hProcess, 0, executableName, sizeof (executableName));

            if (wcsstr(executableName, wstrSystemRootPath) != NULL) {
                goto nextProcess;
            }

            PathStripPathW(executableName);

            ::WideCharToMultiByte(CP_ACP, 0, executableName, -1, debug_buf, 255, NULL, NULL);
            DEBUG_MID_LEVEL << Q_FUNC_INFO << debug_buf;

            for (unsigned k=0; k < SIZEOF_ARRAY(pwstrExcludeProcesses); k++) {
                if (wcsicmp(executableName, pwstrExcludeProcesses[k])== 0) {
                    DEBUG_MID_LEVEL << Q_FUNC_INFO << "skipping " << pwstrExcludeProcesses;
                    goto nextProcess;
                }
            }

            // Get a list of all the modules in this process.

            if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
            {
                bool isDXPresent = false;
                for ( DWORD j = 0; j < (cbNeeded / sizeof(HMODULE)); j++ )
                {
                    WCHAR szModName[MAX_PATH];

                    if ( GetModuleFileNameExW( hProcess, hMods[j], szModName,
                                              sizeof(szModName) / sizeof(WCHAR)))
                    {

                        PathStripPathW(szModName);
                        ::WideCharToMultiByte(CP_ACP, 0, szModName, -1, debug_buf, 255, NULL, NULL);
                        DEBUG_HIGH_LEVEL << Q_FUNC_INFO << debug_buf;

                        if(wcsicmp(szModName, lightpackHooksDllName) == 0) {
                            goto nextProcess;
                        } else {
                            if (wcsicmp(szModName, L"d3d9.dll") == 0 ||
                                wcsicmp(szModName, L"dxgi.dll") == 0 )
                                isDXPresent = true;
                        }
                    }
                }
                if (isDXPresent)
                    processes->append(aProcesses[i]);

            }
nextProcess:
            // Release the handle to the process.
            CloseHandle( hProcess );
        }
    }

    return processes;
}
Exemple #9
0
static void create_snapshot(HWND hwnd, WCHAR* fn) {
    HANDLE h;
    NTSTATUS Status;
    IO_STATUS_BLOCK iosb;
    btrfs_get_file_ids bgfi;
    
    h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    
    if (h != INVALID_HANDLE_VALUE) {
        Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_FILE_IDS, NULL, 0, &bgfi, sizeof(btrfs_get_file_ids));
            
        if (Status == STATUS_SUCCESS && bgfi.inode == 0x100 && !bgfi.top) {
            WCHAR parpath[MAX_PATH], subvolname[MAX_PATH], templ[MAX_PATH], name[MAX_PATH], searchpath[MAX_PATH];
            HANDLE h2, fff;
            btrfs_create_snapshot* bcs;
            ULONG namelen, pathend;
            WIN32_FIND_DATAW wfd;
            SYSTEMTIME time;
            
            StringCchCopyW(parpath, sizeof(parpath) / sizeof(WCHAR), fn);
            PathRemoveFileSpecW(parpath);
            
            StringCchCopyW(subvolname, sizeof(subvolname) / sizeof(WCHAR), fn);
            PathStripPathW(subvolname);
            
            h2 = CreateFileW(parpath, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);

            if (h2 == INVALID_HANDLE_VALUE) {
                ShowError(hwnd, GetLastError());
                CloseHandle(h);
                return;
            }
            
            if (!LoadStringW(module, IDS_SNAPSHOT_FILENAME, templ, MAX_PATH)) {
                ShowError(hwnd, GetLastError());
                CloseHandle(h);
                CloseHandle(h2);
                return;
            }
            
            GetLocalTime(&time);
            
            if (StringCchPrintfW(name, sizeof(name) / sizeof(WCHAR), templ, subvolname, time.wYear, time.wMonth, time.wDay) == STRSAFE_E_INSUFFICIENT_BUFFER) {
                MessageBoxW(hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR);
                CloseHandle(h);
                CloseHandle(h2);
                return;
            }
            
            StringCchCopyW(searchpath, sizeof(searchpath) / sizeof(WCHAR), parpath);
            StringCchCatW(searchpath, sizeof(searchpath) / sizeof(WCHAR), L"\\");
            pathend = wcslen(searchpath);
            
            StringCchCatW(searchpath, sizeof(searchpath) / sizeof(WCHAR), name);
            
            fff = FindFirstFileW(searchpath, &wfd);
            
            if (fff != INVALID_HANDLE_VALUE) {
                ULONG i = wcslen(searchpath), num = 2;
                
                do {
                    FindClose(fff);
                    
                    searchpath[i] = 0;
                    if (StringCchPrintfW(searchpath, sizeof(searchpath) / sizeof(WCHAR), L"%s (%u)", searchpath, num) == STRSAFE_E_INSUFFICIENT_BUFFER) {
                        MessageBoxW(hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR);
                        CloseHandle(h);
                        CloseHandle(h2);
                        return;
                    }

                    fff = FindFirstFileW(searchpath, &wfd);
                    num++;
                } while (fff != INVALID_HANDLE_VALUE);
            }
            
            namelen = wcslen(&searchpath[pathend]) * sizeof(WCHAR);
                        
            bcs = (btrfs_create_snapshot*)malloc(sizeof(btrfs_create_snapshot) - 1 + namelen);
            bcs->subvol = h;
            bcs->namelen = namelen;
            memcpy(bcs->name, &searchpath[pathend], namelen);
            
            Status = NtFsControlFile(h2, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, NULL, 0, bcs, sizeof(btrfs_create_snapshot) - 1 + namelen);
        
            if (Status != STATUS_SUCCESS)
                ShowNtStatusError(hwnd, Status);
            
            CloseHandle(h2);
        }
        
        CloseHandle(h);
    } else
        ShowError(hwnd, GetLastError());
}
/**************************************************************************
 *  IQueryAssociations_GetString
 *
 * Get a file association string from the registry.
 *
 * PARAMS
 *  cfFlags  [I]   ASSOCF_ flags from "shlwapi.h"
 *  str      [I]   Type of string to get (ASSOCSTR enum from "shlwapi.h")
 *  pszExtra [I]   Extra information about the string location
 *  pszOut   [O]   Destination for the association string
 *  pcchOut  [I/O] Length of pszOut
 *
 * RETURNS
 *  Success: S_OK. pszOut contains the string, pcchOut contains its length.
 *  Failure: An HRESULT error code indicating the error.
 */
HRESULT STDMETHODCALLTYPE CQueryAssociations::GetString(
    ASSOCF flags,
    ASSOCSTR str,
    LPCWSTR pszExtra,
    LPWSTR pszOut,
    DWORD *pcchOut)
{
    const ASSOCF unimplemented_flags = ~ASSOCF_NOTRUNCATE;
    DWORD len = 0;
    HRESULT hr;
    WCHAR path[MAX_PATH];

    TRACE("(%p)->(0x%08x, %u, %s, %p, %p)\n", this, flags, str, debugstr_w(pszExtra), pszOut, pcchOut);
    if (flags & unimplemented_flags)
    {
        FIXME("%08x: unimplemented flags\n", flags & unimplemented_flags);
    }
    
    if (!pcchOut)
    {
        return E_UNEXPECTED;
    }
    
    if (!this->hkeySource && !this->hkeyProgID)
    {
        return HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);
    }

    switch (str)
    {
        case ASSOCSTR_COMMAND:
        {
            WCHAR *command;
            hr = this->GetCommand(pszExtra, &command);
            if (SUCCEEDED(hr))
            {
                hr = this->ReturnString(flags, pszOut, pcchOut, command, strlenW(command) + 1);
                HeapFree(GetProcessHeap(), 0, command);
            }
            return hr;
        }
        case ASSOCSTR_EXECUTABLE:
        {
            hr = this->GetExecutable(pszExtra, path, MAX_PATH, &len);
            if (FAILED(hr))
            {
                return hr;
            }
            len++;
            return this->ReturnString(flags, pszOut, pcchOut, path, len);
        }
        case ASSOCSTR_FRIENDLYDOCNAME:
        {
            WCHAR *pszFileType;

            hr = this->GetValue(this->hkeySource, NULL, (void**)&pszFileType, NULL);
            if (FAILED(hr))
            {
                return hr;
            }
            DWORD size = 0;
            DWORD ret = RegGetValueW(HKEY_CLASSES_ROOT, pszFileType, NULL, RRF_RT_REG_SZ, NULL, NULL, &size);
            if (ret == ERROR_SUCCESS)
            {
                WCHAR *docName = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, size));
                if (docName)
                {
                    ret = RegGetValueW(HKEY_CLASSES_ROOT, pszFileType, NULL, RRF_RT_REG_SZ, NULL, docName, &size);
                    if (ret == ERROR_SUCCESS)
                    {
                        hr = this->ReturnString(flags, pszOut, pcchOut, docName, strlenW(docName) + 1);
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ret);
                    }
                    HeapFree(GetProcessHeap(), 0, docName);
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                }
            }
            else
            {
                hr = HRESULT_FROM_WIN32(ret);
            }
            HeapFree(GetProcessHeap(), 0, pszFileType);
            return hr;
        }
        case ASSOCSTR_FRIENDLYAPPNAME:
        {
            PVOID verinfoW = NULL;
            DWORD size, retval = 0;
            UINT flen;
            WCHAR *bufW;
            static const WCHAR translationW[] = L"\\VarFileInfo\\Translation";
            static const WCHAR fileDescFmtW[] = L"\\StringFileInfo\\%04x%04x\\FileDescription";
            WCHAR fileDescW[41];

            hr = this->GetExecutable(pszExtra, path, MAX_PATH, &len);
            if (FAILED(hr))
            {
                return hr;
            }
            retval = GetFileVersionInfoSizeW(path, &size);
            if (!retval)
            {
                goto get_friendly_name_fail;
            }
            verinfoW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, retval);
            if (!verinfoW)
            {
                return E_OUTOFMEMORY;
            }
            if (!GetFileVersionInfoW(path, 0, retval, verinfoW))
            {
                goto get_friendly_name_fail;
            }
            if (VerQueryValueW(verinfoW, translationW, (LPVOID *)&bufW, &flen))
            {
                UINT i;
                DWORD *langCodeDesc = (DWORD *)bufW;
                for (i = 0; i < flen / sizeof(DWORD); i++)
                {
                    sprintfW(fileDescW, fileDescFmtW, LOWORD(langCodeDesc[i]), HIWORD(langCodeDesc[i]));
                    if (VerQueryValueW(verinfoW, fileDescW, (LPVOID *)&bufW, &flen))
                    {
                        /* Does strlenW(bufW) == 0 mean we use the filename? */
                        len = strlenW(bufW) + 1;
                        TRACE("found FileDescription: %s\n", debugstr_w(bufW));
                        hr = this->ReturnString(flags, pszOut, pcchOut, bufW, len);
                        HeapFree(GetProcessHeap(), 0, verinfoW);
                        return hr;
                    }
                }
            }
        get_friendly_name_fail:
            PathRemoveExtensionW(path);
            PathStripPathW(path);
            TRACE("using filename: %s\n", debugstr_w(path));
            hr = this->ReturnString(flags, pszOut, pcchOut, path, strlenW(path) + 1);
            HeapFree(GetProcessHeap(), 0, verinfoW);
            return hr;
        }
        case ASSOCSTR_CONTENTTYPE:
        {
            static const WCHAR Content_TypeW[] = L"Content Type";

            DWORD size = 0;
            DWORD ret = RegGetValueW(this->hkeySource, NULL, Content_TypeW, RRF_RT_REG_SZ, NULL, NULL, &size);
            if (ret != ERROR_SUCCESS)
            {
                return HRESULT_FROM_WIN32(ret);
            }
            WCHAR *contentType = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, size));
            if (contentType != NULL)
            {
                ret = RegGetValueW(this->hkeySource, NULL, Content_TypeW, RRF_RT_REG_SZ, NULL, contentType, &size);
                if (ret == ERROR_SUCCESS)
                {
                    hr = this->ReturnString(flags, pszOut, pcchOut, contentType, strlenW(contentType) + 1);
                }
                else
                {
                    hr = HRESULT_FROM_WIN32(ret);
                }
                HeapFree(GetProcessHeap(), 0, contentType);
            }
            else
            {
                hr = E_OUTOFMEMORY;
            }
            return hr;
        }
        case ASSOCSTR_DEFAULTICON:
        {
            static const WCHAR DefaultIconW[] = L"DefaultIcon";
            DWORD ret;
            DWORD size = 0;
            ret = RegGetValueW(this->hkeyProgID, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, NULL, &size);
            if (ret == ERROR_SUCCESS)
            {
                WCHAR *icon = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, size));
                if (icon)
                {
                    ret = RegGetValueW(this->hkeyProgID, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, icon, &size);
                    if (ret == ERROR_SUCCESS)
                    {
                        hr = this->ReturnString(flags, pszOut, pcchOut, icon, strlenW(icon) + 1);
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ret);
                    }
                    HeapFree(GetProcessHeap(), 0, icon);
                }
                else
                {
                    hr = HRESULT_FROM_WIN32(ret);
                }
            }
            else
            {
                hr = HRESULT_FROM_WIN32(ret);
            }
            return hr;
        }
        case ASSOCSTR_SHELLEXTENSION:
        {
            static const WCHAR shellexW[] = L"ShellEx\\";
            WCHAR keypath[sizeof(shellexW) / sizeof(shellexW[0]) + 39], guid[39];
            CLSID clsid;
            HKEY hkey;

            hr = CLSIDFromString(pszExtra, &clsid);
            if (FAILED(hr))
            {            
                return hr;
            }
            strcpyW(keypath, shellexW);
            strcatW(keypath, pszExtra);
            LONG ret = RegOpenKeyExW(this->hkeySource, keypath, 0, KEY_READ, &hkey);
            if (ret)
            {
                return HRESULT_FROM_WIN32(ret);
            }
            DWORD size = sizeof(guid);
            ret = RegGetValueW(hkey, NULL, NULL, RRF_RT_REG_SZ, NULL, guid, &size);
            RegCloseKey(hkey);
            if (ret)
            {
                return HRESULT_FROM_WIN32(ret);
            }
            return this->ReturnString(flags, pszOut, pcchOut, guid, size / sizeof(WCHAR));
        }
        
        default:
        {
            FIXME("assocstr %d unimplemented!\n", str);
            return E_NOTIMPL;
        }
    }
}