bool MyFormatMessage(DWORD messageID, UString &message) { CSysString messageSys; bool result = MyFormatMessage(messageID, messageSys); message = GetUnicodeString(messageSys); return result; }
bool MyFormatMessage(DWORD messageID, UString &message) { if (g_IsNT) { LPVOID msgBuf; if(::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0) return false; message = (LPCWSTR)msgBuf; ::LocalFree(msgBuf); return true; } CSysString messageSys; bool result = MyFormatMessage(messageID, messageSys); message = GetUnicodeString(messageSys); return result; }
HRESULT CSimpleShlExt::InvokeCommand ( LPCMINVOKECOMMANDINFO pCmdInfo ) { STARTUPINFO startupInfo; PROCESS_INFORMATION processInformation; TCHAR szDir[MAX_PATH]; HKEY hKey; DWORD dwSize; HANDLE hMapFile, hDoneEvent, hWait[2]; LPVOID lpMapAddress; unsigned __int64 nMapSize = m_nFilesLength*sizeof(TCHAR); // If lpVerb really points to a string, ignore this function call and bail out. if ( 0 != HIWORD( pCmdInfo->lpVerb )) return E_INVALIDARG; // Get the command index - the only valid one is 0. if (LOWORD(pCmdInfo->lpVerb) != 0) return E_INVALIDARG; // Get RenameIt.exe directory if (::RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\Rename-It!"), &hKey) != ERROR_SUCCESS) { ::MessageBox(pCmdInfo->hwnd, _T("Unable to open registry key.\nPlease re-install the application."), _T("Rename-It!"), MB_ICONERROR); return S_OK; } dwSize = sizeof(szDir)/sizeof(szDir[0]); if (::RegQueryValueEx(hKey, _T("ExeDir"), NULL, NULL, (LPBYTE)szDir, &dwSize) != ERROR_SUCCESS) { ::MessageBox(pCmdInfo->hwnd, _T("Unable to read registry key.\nPlease re-install the application."), _T("Rename-It!"), MB_ICONERROR); return S_OK; } ::RegCloseKey(hKey); // Create file mapping tstring strMapFileName; strMapFileName.reserve(32); while (true) { // Random name strMapFileName = _T("RenIt-MapFileEvent-"); for (int i=0; i<10; ++i) strMapFileName += _T("0123456789ABCDEF")[rand() % 16]; // Create file mapping hMapFile = ::CreateFileMapping( INVALID_HANDLE_VALUE, // Current file handle NULL, // Default security PAGE_READWRITE, // Read/write permission DWORD(nMapSize >> 32), // Max. object size (high-order) DWORD(nMapSize), // Max. object size (low-order) strMapFileName.c_str()); // Name of mapping object if (hMapFile == NULL) { ::MessageBox(pCmdInfo->hwnd, _T("Unable to create file mapping."), _T("Rename-It!"), MB_ICONERROR); return S_OK; } if (::GetLastError() != ERROR_ALREADY_EXISTS) break; ::CloseHandle(hMapFile); } // Copy data lpMapAddress = ::MapViewOfFile( hMapFile, // Handle to mapping object FILE_MAP_ALL_ACCESS, // Read/write permission 0, // Max. object size (high-order) 0, // Max. object size (low-order) nMapSize); // Map entire file if (lpMapAddress == NULL) { ::MessageBox(pCmdInfo->hwnd, _T("Could not map view of file."), _T("Rename-It!"), MB_ICONERROR); return S_OK; } memcpy(lpMapAddress, m_szFiles, nMapSize); // Create event tstring strEventName; strEventName.reserve(32); while (true) { // Random name strEventName = _T("RenIt-DoneEvent-"); for (int i=0; i<10; ++i) strEventName += _T("0123456789ABCDEF")[rand() % 16]; // Create event if ((hDoneEvent=::CreateEvent(NULL, TRUE, FALSE, strEventName.c_str())) == NULL) { ::MessageBox(pCmdInfo->hwnd, _T("Unable to create event."), _T("Rename-It!"), MB_ICONERROR); return S_OK; } if (::GetLastError() != ERROR_ALREADY_EXISTS) break; ::CloseHandle(hDoneEvent); } // Parameters tstring strApplication; strApplication.reserve(MAX_PATH); strApplication = _T("\""); strApplication += szDir; strApplication += _T("\\RenameIt.exe\""); TCHAR szMaxSize[32]; _stprintf_s(szMaxSize, _T("%I64u"), nMapSize); tstring strCommandLine; strCommandLine.reserve(MAX_PATH); strCommandLine += strApplication; strCommandLine += _T(" /$shell$ext$ "); strCommandLine += strMapFileName; strCommandLine += _T(":"); strCommandLine += szMaxSize; strCommandLine += _T(":"); strCommandLine += strEventName; // Lauch the program ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); std::auto_ptr<TCHAR> szCommandLine(new TCHAR[strCommandLine.length() + 1]); _tcscpy(szCommandLine.get(), strCommandLine.c_str()); if (!::CreateProcess(NULL, szCommandLine.get(), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation)) { LPTSTR lpMsgBuf = NULL; DWORD dwError = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); if (lpMsgBuf) { // Display the error. MyFormatMessage(IDS_CREATE_RENAMEIT_PROCESS_ERROR, strCommandLine.c_str(), lpMsgBuf); // Free the buffer. LocalFree(lpMsgBuf); } else ::MessageBox(NULL, _T("Critical error."), _T("Rename-It!"), MB_ICONSTOP); return S_OK; } // Wait hWait[0] = processInformation.hProcess; hWait[1] = hDoneEvent; ::WaitForMultipleObjects(sizeof(hWait)/sizeof(hWait[0]), hWait, FALSE, INFINITE); ::CloseHandle(processInformation.hThread); ::CloseHandle(processInformation.hProcess); UnmapViewOfFile(lpMapAddress); return S_OK; }