/** @param lpCopyFrom Folder to copy the printer driver files from @return true if copied successfully, false if failed */ bool PrinterInstall::DoCopyFiles(LPCTSTR lpCopyFrom) { TCHAR lpPath[MAX_PATH + 1]; DWORD uSize=0; // Get the Windows printer driver folder if (!GetPrinterDriverDirectory(NULL, NULL, 1, (LPBYTE)lpPath, MAX_PATH + 1, &uSize)) { // Failed?! SetError(-1201); #ifdef TRACE TRACE(_T("Could not get printer driver directory: %d\n"), GetLastError()); #endif return false; } // Copy the files from the lpCopyFrom dir to the destination dir: std::tstring sFrom, sTo; for (STRARRAY::const_iterator i = m_arFiles.begin(); i != m_arFiles.end(); i++) { // Create the full path name for the files sFrom = ConcatPaths(lpCopyFrom, (*i)); sTo = ConcatPaths(lpPath, (*i)); // Now copy if (!::CopyFile(sFrom.c_str(), sTo.c_str(), TRUE)) { DWORD error = GetLastError(); if (error == 0 && !::CopyFile(sFrom.c_str(), sTo.c_str(), FALSE)) { // May be a permissions error or something, // let's ignore } else { SetError(error/*-1202*/); /*TCHAR msg[1024]; _tcscpy_s (msg, 1024, "Failed to copy from\n"); _tcscat_s (msg, 1024, sFrom.c_str()); _tcscat_s (msg, 1024, "\nto\n"); _tcscat_s (msg, 1024, sTo.c_str()); MessageBox (NULL, msg, _T("Error!"), 0);*/ #ifdef TRACE TRACE(_T("Cannot copy file: %d\n"), GetLastError()); #endif return false; } } } return true; }
/** @return true if the printer driver files were removed successfully, false if failed */ bool PrinterInstall::DoRemoveFiles() { TCHAR lpPath[MAX_PATH + 1]; DWORD uSize=0; // Get the Windows printer driver folder if (!::GetPrinterDriverDirectory(NULL, NULL, 1, (LPBYTE)lpPath, MAX_PATH + 1, &uSize)) { // Failed! SetError(-1301); #ifdef TRACE TRACE(_T("Cannot get printer driver directory: %d\n"), GetLastError()); #endif return false; } // Remove all the files: std::tstring sFullPath; for (STRARRAY::const_iterator i = m_arFiles.begin(); i != m_arFiles.end(); i++) { // Create the full path to the file sFullPath = ConcatPaths(lpPath, (*i)); // Delete it if (!::DeleteFile(sFullPath.c_str())) { #ifdef TRACE TRACE(_T("Warning: cannot delete file %s: %d\n"), (*i).c_str(), GetLastError()); #endif } } return true; }
// Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { std::string file; if (number == 0) { file = base_name.string() + "." + extension; } else { file = base_name.string() + "_" + StreamableToString(number) + "." + extension; } return ConcatPaths(directory, FilePath(file)); }
LList <char *> *ListSubDirectoryNames(const char *_dir) { LList<char *> *result = new LList<char *>(); #ifdef WIN32 _finddata_t thisfile; long fileindex; char *dir = ConcatPaths( _dir, "*.*", NULL ); fileindex = _findfirst( dir, &thisfile ); int exitmeplease = 0; while( fileindex != -1 && !exitmeplease ) { if( strcmp( thisfile.name, "." ) != 0 && strcmp( thisfile.name, ".." ) != 0 && (thisfile.attrib & _A_SUBDIR) ) { char *newname = strdup( thisfile.name ); result->PutData( newname ); } exitmeplease = _findnext( fileindex, &thisfile ); } delete[] dir; #else DIR *dir = opendir(_dir); if (dir == NULL) return result; for (struct dirent *entry; (entry = readdir(dir)) != NULL; ) { if (entry->d_name[0] == '.') continue; char fullname[strlen(_dir) + strlen(entry->d_name) + 2]; sprintf(fullname, "%s%s%s", _dir, _dir[0] ? "/" : "", entry->d_name); if (IsDirectory(fullname)) result->PutData( strdup(entry->d_name) ); } closedir(dir); #endif return result; }
/** @param lpMonitorName Name of port monitor @param lpMonitorFile Port monitor DLL filename @param lpFilePath Path where the port monitor file currently resides @return true if installed successfully, false if failed */ bool PrinterInstall::AddPortMonitor(LPCTSTR lpMonitorName, LPCTSTR lpMonitorFile, LPCTSTR lpFilePath) { // Due to certain stupid Windows 7 mechanisms, we need to disable this thing: PVOID oldval = Disable64Redirection(); // Only add the port monitor if it's not already installed: DWORD dwNeeded, dwReturned; ::EnumMonitors(NULL, 1, NULL, 0, &dwNeeded, &dwReturned); if (dwNeeded > 0) { MONITOR_INFO_1* pMonitors = (MONITOR_INFO_1*)new char[dwNeeded]; bool bFound = false; if (::EnumMonitors(NULL, 1, (LPBYTE)pMonitors, dwNeeded, &dwNeeded, &dwReturned)) { for (DWORD i=0;!bFound && (i<dwReturned);i++) bFound = _tcscmp(pMonitors[i].pName, lpMonitorName) == 0; } delete [] pMonitors; if (bFound) return true; } TCHAR lpPath[MAX_PATH + 1]; // Get the Windows system path (where we will install the port monitor) if (!GetSystemDirectory(lpPath, MAX_PATH + 1)) { // Failed SetError(-2001); #ifdef TRACE TRACE(_T("Could not get system directory: %d\n"), GetLastError()); #endif return false; } // Copy the file into the system directory std::tstring sFrom, sTo; sFrom = ConcatPaths(lpFilePath, lpMonitorFile); sTo = ConcatPaths(lpPath, lpMonitorFile); if (!ExistsAsFile(sTo.c_str())) { if (!::CopyFile(sFrom.c_str(), sTo.c_str(), FALSE)) { // Couldn't! SetError(-2002); /*TCHAR msg[1024]; _tcscpy_s (msg, 1024, "Failed to copy from\n"); _tcscat_s (msg, 1024, sFrom.c_str()); _tcscat_s (msg, 1024, "\nto\n"); _tcscat_s (msg, 1024, sTo.c_str()); MessageBox (NULL, msg, _T("Error!"), 0);*/ #ifdef TRACE TRACE(_T("Cannot copy file: %d\n"), GetLastError()); #endif return false; } } // Initialize the data structure MONITOR_INFO_2 info; info.pName = (TCHAR*)lpMonitorName; info.pEnvironment = m_bX64 ? ENVIRONMENT_64 : ENVIRONMENT; info.pDLLName = (TCHAR*)lpMonitorFile; // Add the new monitor if (!::AddMonitor(NULL, 2, (LPBYTE)&info)) { int nError = GetLastError(); // Failed... SetError(-2003); #ifdef TRACE TRACE(_T("Cannot add a port monitor: %d\n"), GetLastError()); #endif return false; } Revert64Redirection(oldval); // Remember the name! m_sPortMonitor = lpMonitorName; return true; }
static BOOLEAN InstallDriver( IN HINF hInf, IN HANDLE hServices, IN HANDLE hDeviceKey, IN LPCWSTR DeviceId, IN LPCWSTR HardwareId) { UNICODE_STRING PathPrefix = RTL_CONSTANT_STRING(L"System32\\DRIVERS\\"); UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service"); UNICODE_STRING ErrorControlU = RTL_CONSTANT_STRING(L"ErrorControl"); UNICODE_STRING ImagePathU = RTL_CONSTANT_STRING(L"ImagePath"); UNICODE_STRING StartU = RTL_CONSTANT_STRING(L"Start"); UNICODE_STRING TypeU = RTL_CONSTANT_STRING(L"Type"); UNICODE_STRING UpperFiltersU = RTL_CONSTANT_STRING(L"UpperFilters"); PWSTR keyboardClass = L"kbdclass\0"; UNICODE_STRING StringU; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hService; INFCONTEXT Context; PCWSTR Driver, ClassGuid, ImagePath; PWSTR FullImagePath; ULONG dwValue; ULONG Disposition; NTSTATUS Status; BOOLEAN deviceInstalled = FALSE; /* Check if we know the hardware */ if (!SpInfFindFirstLine(hInf, L"HardwareIdsDatabase", HardwareId, &Context)) return FALSE; if (!INF_GetDataField(&Context, 1, &Driver)) return FALSE; /* Get associated class GUID (if any) */ if (!INF_GetDataField(&Context, 2, &ClassGuid)) ClassGuid = NULL; /* Find associated driver name */ /* FIXME: check in other sections too! */ if (!SpInfFindFirstLine(hInf, L"BootBusExtenders.Load", Driver, &Context) && !SpInfFindFirstLine(hInf, L"BusExtenders.Load", Driver, &Context) && !SpInfFindFirstLine(hInf, L"SCSI.Load", Driver, &Context) && !SpInfFindFirstLine(hInf, L"InputDevicesSupport.Load", Driver, &Context) && !SpInfFindFirstLine(hInf, L"Keyboard.Load", Driver, &Context)) { INF_FreeData(ClassGuid); INF_FreeData(Driver); return FALSE; } if (!INF_GetDataField(&Context, 1, &ImagePath)) { INF_FreeData(ClassGuid); INF_FreeData(Driver); return FALSE; } /* Prepare full driver path */ dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR); FullImagePath = (PWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue); if (!FullImagePath) { DPRINT1("RtlAllocateHeap() failed\n"); INF_FreeData(ImagePath); INF_FreeData(ClassGuid); INF_FreeData(Driver); return FALSE; } RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength); ConcatPaths(FullImagePath, dwValue / sizeof(WCHAR), 1, ImagePath); DPRINT1("Using driver '%S' for device '%S'\n", ImagePath, DeviceId); /* Create service key */ RtlInitUnicodeString(&StringU, Driver); InitializeObjectAttributes(&ObjectAttributes, &StringU, OBJ_CASE_INSENSITIVE, hServices, NULL); Status = NtCreateKey(&hService, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status); RtlFreeHeap(ProcessHeap, 0, FullImagePath); INF_FreeData(ImagePath); INF_FreeData(ClassGuid); INF_FreeData(Driver); return FALSE; } /* Fill service key */ if (Disposition == REG_CREATED_NEW_KEY) { dwValue = 0; NtSetValueKey(hService, &ErrorControlU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); dwValue = 0; NtSetValueKey(hService, &StartU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); dwValue = SERVICE_KERNEL_DRIVER; NtSetValueKey(hService, &TypeU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); } /* HACK: don't put any path in registry */ NtSetValueKey(hService, &ImagePathU, 0, REG_SZ, (PVOID)ImagePath, (wcslen(ImagePath) + 1) * sizeof(WCHAR)); INF_FreeData(ImagePath); if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0) { DPRINT1("Installing keyboard class driver for '%S'\n", DeviceId); NtSetValueKey(hDeviceKey, &UpperFiltersU, 0, REG_MULTI_SZ, keyboardClass, (wcslen(keyboardClass) + 2) * sizeof(WCHAR)); } INF_FreeData(ClassGuid); /* Associate device with the service we just filled */ Status = NtSetValueKey(hDeviceKey, &ServiceU, 0, REG_SZ, (PVOID)Driver, (wcslen(Driver) + 1) * sizeof(WCHAR)); if (NT_SUCCESS(Status)) { /* Restart the device, so it will use the driver we registered */ deviceInstalled = ResetDevice(DeviceId); } INF_FreeData(Driver); /* HACK: Update driver path */ NtSetValueKey(hService, &ImagePathU, 0, REG_SZ, FullImagePath, (wcslen(FullImagePath) + 1) * sizeof(WCHAR)); RtlFreeHeap(ProcessHeap, 0, FullImagePath); NtClose(hService); return deviceInstalled; }