/** * Retrieves a file's vendor. * Outputs the vendor's name or an error message (if not found/invalid) on stack. * * @param hwndParent Window handle of parent. * @param string_size Size of variable string. * @param variables The actual variable string. * @param stacktop Pointer to a pointer to the current stack. */ VBOXINSTALLHELPER_EXPORT FileGetVendor(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) { NOREF(hwndParent); EXDLL_INIT(); TCHAR szFile[MAX_PATH + 1]; HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR)); if (SUCCEEDED(hr)) { DWORD dwInfoSize = GetFileVersionInfoSize(szFile, NULL /* lpdwHandle */); if (dwInfoSize) { void *pFileInfo = GlobalAlloc(GMEM_FIXED, dwInfoSize); if (pFileInfo) { if (GetFileVersionInfo(szFile, 0, dwInfoSize, pFileInfo)) { LPVOID pvInfo; UINT puInfoLen; if (VerQueryValue(pFileInfo, _T("\\VarFileInfo\\Translation"), &pvInfo, &puInfoLen)) { WORD wCodePage = LOWORD(*(DWORD*)pvInfo); WORD wLanguageID = HIWORD(*(DWORD*)pvInfo); TCHAR szQuery[MAX_PATH]; #pragma warning(suppress:4995) /* warning C4995: '_sntprintf': name was marked as #pragma deprecated */ _sntprintf(szQuery, sizeof(szQuery), _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage,wLanguageID); LPCTSTR pcData; if (VerQueryValue(pFileInfo, szQuery,(void**)&pcData, &puInfoLen)) { pushstring(pcData); } else hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } else hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } GlobalFree(pFileInfo); } else hr = __HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); } else hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } if (FAILED(hr)) vboxPushResultAsString(hr); }
HRESULT AddGadget(IDesktopGadget *pDG, PCWSTR pszGadgetPath) { // Note that RunGadget will return S_OK even if the gadget fails to load // due to a problem with the gadget itself. The return value from // RunGadget just indicates whether the request succeeded or not. HRESULT hr = pDG->RunGadget(pszGadgetPath); if (FAILED(hr)) { switch (hr) { case SCHED_E_ALREADY_RUNNING: wprintf(L"Gadget '%s' is already running!\n", pszGadgetPath); hr = S_FALSE; break; case __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): wprintf(L"Gadget '%s' not found!\n", pszGadgetPath); break; default: wprintf(L"RunGadget '%s' failed, error=%X\n", pszGadgetPath, hr); break; } } return hr; }
HRESULT PipeStream::OnCustomRequested( HandleStream::AsyncContext* handle_context) { auto context = static_cast<AsyncContext*>(handle_context); BOOL succeeded; switch (context->type) { case PipeRequest::WaitForConnection: succeeded = ConnectNamedPipe(handle_, context); break; case PipeRequest::Transact: succeeded = TransactNamedPipe(handle_, context->buffer, context->length, context->buffer2, context->length2, nullptr, context); break; default: assert(false); return E_NOTIMPL; } DWORD error = GetLastError(); if (!succeeded && error != ERROR_IO_PENDING) { if (error == ERROR_PIPE_CONNECTED && context->hEvent != NULL) SetEvent(context->hEvent); return __HRESULT_FROM_WIN32(error); } return S_OK; }
HRESULT BaseWindow::Register() { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WindowProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = m_hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MenuName(); wcex.lpszClassName = ClassName(); wcex.hIconSm = NULL; ATOM atom = RegisterClassEx(&wcex); if (atom == 0) { return __HRESULT_FROM_WIN32(GetLastError()); } else { return S_OK; } }
HRESULT BaseWindow::Create(HINSTANCE hInstance) { m_hInstance = hInstance; HRESULT hr = Register(); if (SUCCEEDED(hr)) { HWND hwnd = CreateWindow( ClassName(), WindowName(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, m_hInstance, this); if (hwnd == 0) { hr = __HRESULT_FROM_WIN32(GetLastError()); } } return hr; }
HRESULT CReplDriverBase::ReadLine() noexcept { // Empty the line buffer. SecureZeroMemory(m_pszBuffer, BUFFER_SIZE); // Keep reading until the buffer is full or the loop returns. HRESULT hr = S_OK; SIZE_T cchUsed = 0; CHAR *pchPos = m_pszBuffer; while (cchUsed < BUFFER_SIZE) { // Read the next character. ULONG fReceived = FALSE; hr = m_pInput->Read(pchPos, 1, &fReceived); if (hr == __HRESULT_FROM_WIN32(ERROR_NETNAME_DELETED)) { // File API way of telling us the client has disconnected, so return that error. return E_DISCONNECTED; } else if (FAILED(hr)) { // Other general failures. return hr; } if (fReceived) { switch (*pchPos) { case '\n': case '\r': // Don't leave the CRLF characters on the end. *pchPos = 0; // If the pointer did not move, then the line is empty. return m_pszBuffer.m_pData != pchPos ? S_OK : S_FALSE; default: ++pchPos; ++cchUsed; } } else { // No more data would mean the end of the input has been reached, this is either: // 1. Socket I/O would have indicated a disconnection from the client side. // 2. The console or terminal has been closed. // 3. The end of a pipe or file. return E_DISCONNECTED; } } // If the line will not fit in the buffer, consider it an error, this should prevent any // buffer overrun exploits. return E_NOT_SUFFICIENT_BUFFER; }
/** * Pops (gets) a value from the internal NSIS stack. * Since the supplied popstring() method easily can cause buffer * overflows, use vboxPopString() instead! * * @return HRESULT * @param pszDest Pointer to pre-allocated string to store result. * @param cchDest Size (in characters) of pre-allocated string. */ static HRESULT vboxPopString(TCHAR *pszDest, size_t cchDest) { HRESULT hr = S_OK; if (!g_stacktop || !*g_stacktop) hr = __HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE); else { stack_t *pStack = (*g_stacktop); if (pStack) { hr = StringCchCopy(pszDest, cchDest, pStack->text); if (SUCCEEDED(hr)) { *g_stacktop = pStack->next; GlobalFree((HGLOBAL)pStack); } } else hr = __HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE); } return hr; }
HRESULT AllocGetWindowText(HWND hwnd, WCHAR **pszText, DWORD *pcchLen) { if (pszText == NULL || pcchLen == NULL) { return E_POINTER; } *pszText = NULL; int cch = GetWindowTextLength(hwnd); if (cch < 0) { return E_UNEXPECTED; } PWSTR pszTmp = (PWSTR)CoTaskMemAlloc(sizeof(WCHAR) * (cch + 1)); // Includes room for terminating NULL character if (!pszTmp) { return E_OUTOFMEMORY; } if (cch == 0) { pszTmp[0] = L'\0'; // No text. } else { int res = GetWindowText(hwnd, pszTmp, (cch + 1)); // Size includes terminating null character. // GetWindowText returns 0 if (a) there is no text or (b) it failed. // We checked for (a) already, so 0 means failure here. if (res == 0) { CoTaskMemFree(pszTmp); return __HRESULT_FROM_WIN32(GetLastError()); } } // If we got here, szTmp is valid, so return it to the caller. *pszText = pszTmp; // Return the length NOT including the '\0'. *pcchLen = static_cast<DWORD>(cch); return S_OK; }
HRESULT v_ExecuteLibCommand() { HRESULT hr = _plib->SetDefaultSaveFolder(_dsft, _psiFolder); if (FAILED(hr)) { if (hr == __HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) { RuntimeError(L"The specified folder is not included in the library.\n"); } else { RuntimeError(L"Error %#08x setting default save location to %s.\n", hr, _pszFolderPath); } } return hr; }
static HRESULT vboxPopULong(PULONG pulValue) { HRESULT hr = S_OK; if (!g_stacktop || !*g_stacktop) hr = __HRESULT_FROM_WIN32(ERROR_EMPTY); else { stack_t *pStack = (*g_stacktop); if (pStack) { *pulValue = strtoul(pStack->text, NULL, 10 /* Base */); *g_stacktop = pStack->next; GlobalFree((HGLOBAL)pStack); } } return hr; }
HRESULT Control::Create(const CREATESTRUCT& create) { if (m_hwnd != NULL) { // The control was already created. return E_FAIL; } if (create.hwndParent == NULL) { return E_INVALIDARG; } HINSTANCE hinst = create.hInstance; if (hinst == NULL) { hinst = GetInstance(); } if (hinst == NULL) { return E_INVALIDARG; } HWND hwnd = CreateWindowEx( create.dwExStyle, create.lpszClass, create.lpszName, create.style | WS_CHILD | WS_VISIBLE, create.x, create.y, create.cx, create.cy, create.hwndParent, create.hMenu, hinst, create.lpCreateParams); if (hwnd== 0) { return __HRESULT_FROM_WIN32(GetLastError()); } SetWindow(hwnd); return S_OK; };
static HRESULT vboxChar2WCharAlloc(const char *pszString, PWCHAR *ppwString) { HRESULT hr; int iLen = strlen(pszString) + 2; WCHAR *pwString = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, iLen * sizeof(WCHAR)); if (!pwString) hr = __HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); else { if (MultiByteToWideChar(CP_ACP, 0, pszString, -1, pwString, iLen) == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); HeapFree(GetProcessHeap(), 0, pwString); } else { hr = S_OK; *ppwString = pwString; } } return hr; }
HRESULT Slider_Init() { WNDCLASSEX wce; ZeroMemory(&wce, sizeof(wce)); wce.cbSize = sizeof(WNDCLASSEX); wce.lpfnWndProc = SliderControl::Slider_WndProc; wce.hInstance = GetInstance(); wce.lpszClassName = SliderControl::ClassName; wce.cbWndExtra = sizeof(SliderControl::Slider_Info); // Reserve space for slider instance data ATOM a = RegisterClassEx(&wce); if (a == 0) { return __HRESULT_FROM_WIN32(GetLastError()); } else { return S_OK; } }
inline HRESULT UnregisterObject(const GUID& guid) { WCHAR achTemp[MAX_PATH]; HRESULT hr = CreateObjectKeyName(guid, achTemp, MAX_PATH); if (SUCCEEDED(hr)) { // Delete the key recursively. DWORD res = RegDeleteTree(HKEY_CLASSES_ROOT, achTemp); if (res == ERROR_SUCCESS) { hr = S_OK; } else { hr = __HRESULT_FROM_WIN32(res); } } return hr; }
HRESULT MainWindow::OnCreate() { HRESULT hr = S_OK; // Create the background brush. brush = CreateHatchBrush(HS_BDIAGONAL, RGB(0, 0x80, 0xFF)); if (brush == NULL) { hr = __HRESULT_FROM_WIN32(GetLastError()); } // Create the rebar control. if (SUCCEEDED(hr)) { hr = rebar.Create(m_hInstance, m_hwnd, IDC_REBAR_CONTROL); } // Create the toolbar control. if (SUCCEEDED(hr)) { hr = toolbar.Create(m_hInstance, m_hwnd, IDC_TOOLBAR, TBSTYLE_FLAT | TBSTYLE_TOOLTIPS); } // Set the image list for toolbar buttons (normal state). if (SUCCEEDED(hr)) { hr = toolbar.SetImageList( Toolbar::Normal, // Image list for normal state IDB_TOOLBAR_IMAGES_NORMAL, // Bitmap resource Size(48, 48), // Size of each button 5, // Number of buttons RGB(0xFF, 0x00, 0xFF) // Color mask ); } // Set the image list for toolbar buttons (disabled state). if (SUCCEEDED(hr)) { hr = toolbar.SetImageList( Toolbar::Disabled, // Image list for normal state IDB_TOOLBAR_IMAGES_DISABLED, // Bitmap resource Size(48, 48), // Size of each button 5, // Number of buttons RGB(0xFF, 0x00, 0xFF) // Color mask ); } // Add buttons to the toolbar. if (SUCCEEDED(hr)) { // Play hr = toolbar.AddButton(Toolbar::Button(ID_IMAGE_PLAY, IDC_BUTTON_PLAY)); } if (SUCCEEDED(hr)) { // Stop hr = toolbar.AddButton(Toolbar::Button(ID_IMAGE_STOP, IDC_BUTTON_STOP)); } if (SUCCEEDED(hr)) { // Pause hr = toolbar.AddButton(Toolbar::Button(ID_IMAGE_PAUSE, IDC_BUTTON_PAUSE)); } if (SUCCEEDED(hr)) { // Mute hr = toolbar.AddButton(Toolbar::Button(ID_IMAGE_MUTE_OFF, IDC_BUTTON_MUTE)); } // Add the toolbar to the rebar control. if (SUCCEEDED(hr)) { hr = rebar.AddBand(toolbar.Window(), 0); } //// Create the slider for seeking. if (SUCCEEDED(hr)) { hr = Slider_Init(); // Initialize the Slider control. } if (SUCCEEDED(hr)) { hr = seekbar.Create(m_hwnd, Rect(0, 0, 300, 16), IDC_SEEKBAR); } if (SUCCEEDED(hr)) { hr = seekbar.SetThumbBitmap(IDB_SLIDER_THUMB); seekbar.SetBackground(CreateSolidBrush(RGB(239, 239, 231))); seekbar.Enable(FALSE); } if (SUCCEEDED(hr)) { hr = rebar.AddBand(seekbar.Window(), 1); } //// Create the slider for changing the volume. if (SUCCEEDED(hr)) { hr = volumeSlider.Create(m_hwnd, Rect(0, 0, 100, 32), IDC_VOLUME); } if (SUCCEEDED(hr)) { hr = volumeSlider.SetThumbBitmap(IDB_SLIDER_VOLUME); volumeSlider.SetBackground(CreateSolidBrush(RGB(239, 239, 231))); volumeSlider.Enable(TRUE); // Set the range of the volume slider. In my experience, only the top half of the // range is audible. volumeSlider.SetRange(MIN_VOLUME / 2, MAX_VOLUME); volumeSlider.SetPosition(MAX_VOLUME); } if (SUCCEEDED(hr)) { hr = rebar.AddBand(volumeSlider.Window(), 2); } // Create the DirectShow player object. if (SUCCEEDED(hr)) { m_pPlayer = new DShowPlayer(m_hwnd); if (m_pPlayer == NULL) { hr = E_OUTOFMEMORY; } } // Set the event notification window. if (SUCCEEDED(hr)) { hr = m_pPlayer->SetEventWindow(m_hwnd, WM_GRAPH_EVENT); } // Set default UI state. if (SUCCEEDED(hr)) { UpdateUI(); } return hr; }
/** * Shows a balloon message using VBoxTray's notification area in the * Windows task bar. * * @param hwndParent Window handle of parent. * @param string_size Size of variable string. * @param variables The actual variable string. * @param stacktop Pointer to a pointer to the current stack. */ VBOXINSTALLHELPER_EXPORT VBoxTrayShowBallonMsg(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) { EXDLL_INIT(); char szMsg[256]; char szTitle[128]; HRESULT hr = vboxPopString(szMsg, sizeof(szMsg) / sizeof(char)); if (SUCCEEDED(hr)) hr = vboxPopString(szTitle, sizeof(szTitle) / sizeof(char)); /** @todo Do we need to restore the stack on failure? */ if (SUCCEEDED(hr)) { RTR3InitDll(0); uint32_t cbMsg = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG) + strlen(szMsg) + 1 /* Include terminating zero */ + strlen(szTitle) + 1; /* Dito. */ Assert(cbMsg); PVBOXTRAYIPCMSG_SHOWBALLOONMSG pIpcMsg = (PVBOXTRAYIPCMSG_SHOWBALLOONMSG)RTMemAlloc(cbMsg); if (pIpcMsg) { /* Stuff in the strings. */ memcpy(pIpcMsg->szMsgContent, szMsg, strlen(szMsg) + 1); memcpy(pIpcMsg->szMsgTitle, szTitle, strlen(szTitle) + 1); /* Pop off the values in reverse order from the stack. */ if (SUCCEEDED(hr)) hr = vboxPopULong((ULONG*)&pIpcMsg->uType); if (SUCCEEDED(hr)) hr = vboxPopULong((ULONG*)&pIpcMsg->uShowMS); if (SUCCEEDED(hr)) { RTLOCALIPCSESSION hSession = 0; int rc = vboxConnectToVBoxTray(&hSession); if (RT_SUCCESS(rc)) { VBOXTRAYIPCHEADER ipcHdr = { VBOXTRAY_IPC_HDR_MAGIC, 0 /* Header version */, VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG, cbMsg }; rc = RTLocalIpcSessionWrite(hSession, &ipcHdr, sizeof(ipcHdr)); if (RT_SUCCESS(rc)) rc = RTLocalIpcSessionWrite(hSession, pIpcMsg, cbMsg); int rc2 = RTLocalIpcSessionClose(hSession); if (RT_SUCCESS(rc)) rc = rc2; } if (RT_FAILURE(rc)) hr = __HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE); } RTMemFree(pIpcMsg); } else hr = __HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } /* Push simple return value on stack. */ SUCCEEDED(hr) ? pushstring("0") : pushstring("1"); }
/** * Retrieves a file's architecture (x86 or amd64). * Outputs "x86", "amd64" or an error message (if not found/invalid) on stack. * * @param hwndParent Window handle of parent. * @param string_size Size of variable string. * @param variables The actual variable string. * @param stacktop Pointer to a pointer to the current stack. */ VBOXINSTALLHELPER_EXPORT FileGetArchitecture(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) { EXDLL_INIT(); TCHAR szFile[MAX_PATH + 1]; HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR)); if (SUCCEEDED(hr)) { /* See: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx */ FILE *pFh = fopen(szFile, "rb"); if (pFh) { /* Assume the file is invalid. */ hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID); BYTE byOffsetPE; /* Absolute offset of PE signature. */ /* Do some basic validation. */ /* Check for "MZ" header (DOS stub). */ BYTE byBuf[255]; if ( fread(&byBuf, sizeof(BYTE), 2, pFh) == 2 && !memcmp(&byBuf, "MZ", 2)) { /* Seek to 0x3C to get the PE offset. */ if (!fseek(pFh, 60L /*0x3C*/, SEEK_SET)) { /* Read actual offset of PE signature. */ if (fread(&byOffsetPE, sizeof(BYTE), 1, pFh) == 1) { /* ... and seek to it. */ if (!fseek(pFh, byOffsetPE, SEEK_SET)) { /* Validate PE signature. */ if (fread(byBuf, sizeof(BYTE), 4, pFh) == 4) { if (!memcmp(byBuf, "PE\0\0", 4)) hr = S_OK; } } } } } /* Validation successful? */ if (SUCCEEDED(hr)) { BYTE byOffsetCOFF = byOffsetPE + 0x4; /* Skip PE signature. */ /** @todo When we need to do more stuff here, we probably should * mmap the file w/ a struct so that we easily could access * all the fixed size stuff. Later. */ /* Jump to machine type (first entry, 2 bytes): * Use absolute PE offset retrieved above. */ if (!fseek(pFh, byOffsetCOFF, SEEK_SET)) { WORD wMachineType; if (fread(&wMachineType, 1, sizeof(wMachineType), pFh) == 2) { switch (wMachineType) { case 0x14C: /* Intel 86 */ pushstring("x86"); break; case 0x8664: /* AMD64 / x64 */ pushstring("amd64"); break; default: hr = __HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); break; } } else hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID); } else hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID); } fclose(pFh); } else hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } if (FAILED(hr)) vboxPushResultAsString(hr); }
inline HRESULT RegisterObject(HMODULE hModule, const GUID& guid, const WCHAR *sDescription, const WCHAR *sThreadingModel) { HKEY hKey = NULL; HKEY hSubkey = NULL; WCHAR achTemp[MAX_PATH]; // Create the name of the key from the object's CLSID HRESULT hr = CreateObjectKeyName(guid, achTemp, MAX_PATH); // Create the new key. if (SUCCEEDED(hr)) { LONG lreturn = RegCreateKeyEx( HKEY_CLASSES_ROOT, (LPCWSTR)achTemp, // subkey 0, // reserved NULL, // class string (can be NULL) REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, // security attributes &hKey, NULL // receives the "disposition" (is it a new or existing key) ); hr = __HRESULT_FROM_WIN32(lreturn); } // The default key value is a description of the object. if (SUCCEEDED(hr)) { hr = SetKeyValue(hKey, NULL, sDescription); } // Create the "InprocServer32" subkey if (SUCCEEDED(hr)) { const WCHAR *sServer = L"InprocServer32"; LONG lreturn = RegCreateKeyEx(hKey, sServer, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubkey, NULL); hr = __HRESULT_FROM_WIN32(lreturn); } // The default value for this subkey is the path to the DLL. // Get the name of the module ... if (SUCCEEDED(hr)) { DWORD res = GetModuleFileName(hModule, achTemp, MAX_PATH); if (res == 0) { hr = __HRESULT_FROM_WIN32(GetLastError()); } if (res == MAX_PATH) { hr = E_FAIL; // buffer too small } } // ... and set the default key value. if (SUCCEEDED(hr)) { hr = SetKeyValue(hSubkey, NULL, achTemp); } // Add a new value to the subkey, for "ThreadingModel" = <threading model> if (SUCCEEDED(hr)) { hr = SetKeyValue(hSubkey, L"ThreadingModel", sThreadingModel); } // close hkeys if (hSubkey != NULL) { RegCloseKey( hSubkey ); } if (hKey != NULL) { RegCloseKey( hKey ); } return hr; }
/** * Retrieves a file's architecture (x86 or amd64). * Outputs "x86", "amd64" or an error message (if not found/invalid) on stack. * * @param hwndParent Window handle of parent. * @param string_size Size of variable string. * @param variables The actual variable string. * @param stacktop Pointer to a pointer to the current stack. */ VBOXINSTALLHELPER_EXPORT FileGetArchitecture(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) { NOREF(hwndParent); EXDLL_INIT(); TCHAR szFile[MAX_PATH + 1]; HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR)); if (SUCCEEDED(hr)) { /* See: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx */ FILE *pFh = fopen(szFile, "rb"); if (pFh) { /* Assume the file is invalid. */ hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID); BYTE offPeHdr = 0; /* Absolute offset of PE signature. */ /* Do some basic validation. */ /* Check for "MZ" header (DOS stub). */ BYTE byBuf[255]; if ( fread(&byBuf, sizeof(BYTE), 2, pFh) == 2 && !memcmp(&byBuf, "MZ", 2)) { /* Seek to 0x3C to get the PE offset. */ if (!fseek(pFh, 60L /*0x3C*/, SEEK_SET)) { /* Read actual offset of PE signature. */ /** @todo r=bird: You've obviously no clue about the structure you're messing with here. The field is NOT a BYTE * field but a int32_t/uint32_t! The MZ header is defined as IMAGE_DOS_HEADER by windows.h (well, winnt.h), and the * field you're accessing is e_lfanew. Please rewrite this hack to use the structures! (Also, the MZ structure is * OPTIONAL, just in case you didn't know.) */ #ifdef DEBUG_andy # error "Fix this" #endif if (fread(&offPeHdr, sizeof(BYTE), 1, pFh) == 1) { /* ... and seek to it. */ if (!fseek(pFh, offPeHdr, SEEK_SET)) { /* Validate PE signature. */ if (fread(byBuf, sizeof(BYTE), 4, pFh) == 4) { if (!memcmp(byBuf, "PE\0\0", 4)) hr = S_OK; } } } } } /* Validation successful? */ if (SUCCEEDED(hr)) { BYTE offFileHeaderMachineField = offPeHdr + 0x4; /* Skip PE signature. */ /** @todo When we need to do more stuff here, we probably should * mmap the file w/ a struct so that we easily could access * all the fixed size stuff. Later. */ /* Jump to machine type (first entry, 2 bytes): * Use absolute PE offset retrieved above. */ if (!fseek(pFh, offFileHeaderMachineField, SEEK_SET)) { WORD wMachineType; if (fread(&wMachineType, 1, sizeof(wMachineType), pFh) == 2) { switch (wMachineType) { case 0x14C: /* Intel 86 */ pushstring("x86"); break; case 0x8664: /* AMD64 / x64 */ pushstring("amd64"); break; default: hr = __HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); break; } } else hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID); } else hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID); } fclose(pFh); } else hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } if (FAILED(hr)) vboxPushResultAsString(hr); }