//=================================== void DirMonitor::ScanDirectoryForChanges_CS () { // Search for all files in this directory wchar filespec[MAX_PATH]; PathCombineW(filespec, m_directory, L"*"); // Start search WIN32_FIND_DATAW data; HANDLE find = FindFirstFileW(filespec, &data); if (find == INVALID_HANDLE_VALUE) { LOG_OS_LAST_ERROR(L"FindFirstFileW"); return; } // Search for watched files do { // Ignore directories if (data.dwFileAttributes & (FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_DIRECTORY)) continue; // Convert to lowercase for hash matching wchar * filename = PathFindFileNameW(data.cFileName); CharLowerW(filename); // Reparse if file changed CheckReparseFile_CS(filename); } while (FindNextFileW(find, &data)); // Cleanup FindClose(find); }
/************************************************************************* * PathCombine [SHELL32.37] */ LPVOID WINAPI PathCombineAW( LPVOID szDest, LPCVOID lpszDir, LPCVOID lpszFile) { if (SHELL_OsIsUnicode()) return PathCombineW( szDest, lpszDir, lpszFile ); return PathCombineA( szDest, lpszDir, lpszFile ); }
bool _PathCombine(LPWSTR dest,const LPWSTR dir,const LPWSTR file) { LPWSTR p=(LPWSTR)file; if (p) { while ((*p == '\\') || (*p == '/')) p++; } return (!PathCombineW(dest,dir,p)) ? false:true; }
BOOL PathToCombineW(LPWSTR lpfile, size_t str_len) { if ( dll_module && lpfile[1] != L':' ) { wchar_t buf_modname[VALUE_LEN+1] = {0}; charTochar(lpfile); if ( GetModuleFileNameW( dll_module, buf_modname, VALUE_LEN) > 0) { wchar_t tmp_path[MAX_PATH] = {0}; PathRemoveFileSpecW(buf_modname); if ( PathCombineW(tmp_path,buf_modname,lpfile) ) { int n = _snwprintf(lpfile,str_len,L"%ls",tmp_path); lpfile[n] = L'\0'; } } } return TRUE; }
static void join(wchar_t *buffer, const wchar_t *stuff) { if (_PathCchCombineEx_Initialized == 0) { HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll"); if (pathapi) _PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx"); else _PathCchCombineEx = NULL; _PathCchCombineEx_Initialized = 1; } if (_PathCchCombineEx) { if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0))) Py_FatalError("buffer overflow in getpathp.c's join()"); } else { if (!PathCombineW(buffer, buffer, stuff)) Py_FatalError("buffer overflow in getpathp.c's join()"); } }
static int wfio_realpathw(wchar_t *relpath, size_t relpath_len TSRMLS_DC) { char *p; char workdir[MAXPATHLEN] = {0}; wchar_t workdirw[MAX_PATH] = {0}; wchar_t newpathw[MAX_PATH] = {0}; if (relpath[0] == L'\\' || relpath[0] == L'/') return 0; p = VCWD_GETCWD(workdir, MAXPATHLEN); if (p != NULL) { MultiByteToWideChar(CP_ACP, 0, workdir, MAXPATHLEN, workdirw, MAX_PATH); PathCombineW(newpathw, workdirw, relpath); wcsncpy(relpath, newpathw, relpath_len); return 0; } else { return -1; } }
BOOL PathToCombineW(LPWSTR lpfile, size_t str_len) { size_t n = 1; if ( lpfile[0] == L'%' ) { WCHAR buf_env[VALUE_LEN+1] = {0}; while ( lpfile[n] != L'\0' ) { if ( lpfile[n] == L'%' ) { break; } ++n; } if ( n < str_len ) { _snwprintf(buf_env, n+1 ,L"%ls", lpfile); } if ( wcslen(buf_env) > 1 && ExpandEnvironmentStringsW(buf_env,buf_env,VALUE_LEN) > 0 ) { WCHAR tmp_env[VALUE_LEN+1] = {0}; _snwprintf(tmp_env, str_len ,L"%ls%ls", buf_env, &lpfile[n+1]); n = _snwprintf(lpfile, str_len ,L"%ls", tmp_env); } } if ( lpfile[1] != L':' ) { WCHAR buf_modname[VALUE_LEN+1] = {0}; charTochar(lpfile); if ( GetModuleFileNameW( dll_module, buf_modname, VALUE_LEN) > 0) { WCHAR tmp_path[MAX_PATH] = {0}; PathRemoveFileSpecW(buf_modname); if ( PathCombineW(tmp_path,buf_modname,lpfile) ) { n = _snwprintf(lpfile,str_len,L"%ls",tmp_path); } } } return (n>0); }
int ensure_absolute_path(wchar_t *out, const wchar_t *in, int length) { if(!wcsncmp(in, L"\\??\\", 4)) { length -= 4, in += 4; wcsncpy(out, in, length < MAX_PATH ? length : MAX_PATH); return out[length] = 0, length; } else if(in[1] != ':' || (in[2] != '\\' && in[2] != '/')) { wchar_t cur_dir[MAX_PATH], fname[MAX_PATH]; GetCurrentDirectoryW(ARRAYSIZE(cur_dir), cur_dir); // ensure the filename is zero-terminated wcsncpy(fname, in, length < MAX_PATH ? length : MAX_PATH); fname[length] = 0; PathCombineW(out, cur_dir, fname); return lstrlenW(out); } else { wcsncpy(out, in, length < MAX_PATH ? length : MAX_PATH); return out[length] = 0, length; } }
static void copy_file(LPCWSTR source, LPCWSTR destination) { WCHAR destfile[MAX_PATH]; /* append source filename if destination is a directory */ if (PathIsDirectoryW(destination)) { PathCombineW(destfile, destination, PathFindFileNameW(source)); destination = destfile; } if (PathFileExistsW(destination) && !force_mode) { static const WCHAR overwriteMsg[] = {'O','v','e','r','w','r','i','t','e',' ','"','%','s','"','?',0}; static const WCHAR titleMsg[] = {'E','x','t','r','a','c','t',0}; WCHAR msg[MAX_PATH+100]; snprintfW(msg, sizeof(msg)/sizeof(msg[0]), overwriteMsg, destination); if (MessageBoxW(NULL, msg, titleMsg, MB_YESNO | MB_ICONWARNING) != IDYES) return; } WINE_TRACE("copying %s to %s\n", wine_dbgstr_w(source), wine_dbgstr_w(destination)); CopyFileW(source, destination, FALSE); }
/* 必须使用进程依赖crt的wputenv函数追加环境变量 */ unsigned WINAPI SetPluginPath(void * pParam) { typedef int (__cdecl *_pwrite_env)(LPCWSTR envstring); int ret = 0; HMODULE hCrt =NULL; _pwrite_env write_env = NULL; char msvc_crt[CRT_LEN+1] = {0}; LPWSTR lpstring; if ( !find_msvcrt(msvc_crt,CRT_LEN) ) { return (0); } if ( (hCrt = GetModuleHandleA(msvc_crt)) == NULL ) { return (0); } if ( profile_path[1] != L':' ) { if (!ini_ready(profile_path,MAX_PATH)) { return (0); } } write_env = (_pwrite_env)GetProcAddress(hCrt,"_wputenv"); if ( write_env == NULL ) { return (0); } if ( (lpstring = (LPWSTR)SYS_MALLOC(MAX_ENV_SIZE)) == NULL ) { return (0); } if ( (ret = GetPrivateProfileSectionW(L"Env", lpstring, MAX_ENV_SIZE-1, profile_path)) > 0 ) { LPWSTR strKey = lpstring; while(*strKey != L'\0') { if ( stristrW(strKey, L"NpluginPath") ) { WCHAR lpfile[VALUE_LEN+1]; if ( read_appkey(L"Env",L"NpluginPath",lpfile,sizeof(lpfile)) ) { WCHAR env_string[VALUE_LEN+1] = {0}; PathToCombineW(lpfile, VALUE_LEN); if ( _snwprintf(env_string,VALUE_LEN,L"%ls%ls",L"MOZ_PLUGIN_PATH=",lpfile) > 0) { ret = write_env( (LPCWSTR)env_string ); } } } else if ( stristrW(strKey, L"VimpPentaHome") ) { WCHAR lpfile[VALUE_LEN+1]; if ( read_appkey(L"Env",L"VimpPentaHome",lpfile,sizeof(lpfile)) ) { WCHAR env_string[VALUE_LEN+1] = {0}; if (lpfile[1] != L':') { WCHAR vimp_path[VALUE_LEN+1] = {0}; charTochar(lpfile); if ( PathCombineW(vimp_path,portable_data_path,lpfile) ) { int n = _snwprintf(lpfile,VALUE_LEN,L"%ls",vimp_path); lpfile[n] = L'\0'; } } if ( _snwprintf(env_string,VALUE_LEN,L"%ls%ls",L"HOME=",lpfile) > 0) { ret = write_env( (LPCWSTR)env_string ); } } } else if (stristrW(strKey, L"MOZ_GMP_PATH")) { WCHAR lpfile[VALUE_LEN+1]; if ( read_appkey(L"Env",L"MOZ_GMP_PATH",lpfile,sizeof(lpfile)) ) { WCHAR env_string[VALUE_LEN+1] = {0}; PathToCombineW(lpfile, VALUE_LEN); if ( _snwprintf(env_string,VALUE_LEN,L"%ls%ls",L"MOZ_GMP_PATH=",lpfile) > 0) { ret = write_env( (LPCWSTR)env_string ); } } } else if (stristrW(strKey, L"TmpDataPath")) { /* the PATH environment variable does not exist */ } else { ret = write_env( (LPCWSTR)strKey ); } strKey += wcslen(strKey)+1; } } SYS_FREE(lpstring); return (1); }
/************************************************************************* * SHGetFileInfoW [SHELL32.@] * */ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags ) { WCHAR szLocation[MAX_PATH], szFullPath[MAX_PATH]; int iIndex; DWORD_PTR ret = TRUE; DWORD dwAttributes = 0; IShellFolder * psfParent = NULL; IExtractIconW * pei = NULL; LPITEMIDLIST pidlLast = NULL, pidl = NULL; HRESULT hr = S_OK; BOOL IconNotYetLoaded=TRUE; UINT uGilFlags = 0; HIMAGELIST big_icons, small_icons; TRACE("%s fattr=0x%x sfi=%p(attr=0x%08x) size=0x%x flags=0x%x\n", (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags); if (!path) return FALSE; /* windows initializes these values regardless of the flags */ if (psfi != NULL) { psfi->szDisplayName[0] = '\0'; psfi->szTypeName[0] = '\0'; psfi->iIcon = 0; } if (!(flags & SHGFI_PIDL)) { /* SHGetFileInfo should work with absolute and relative paths */ if (PathIsRelativeW(path)) { GetCurrentDirectoryW(MAX_PATH, szLocation); PathCombineW(szFullPath, szLocation, path); } else { lstrcpynW(szFullPath, path, MAX_PATH); } } if (flags & SHGFI_EXETYPE) { if (flags != SHGFI_EXETYPE) return 0; return shgfi_get_exe_type(szFullPath); } /* * psfi is NULL normally to query EXE type. If it is NULL, none of the * below makes sense anyway. Windows allows this and just returns FALSE */ if (psfi == NULL) return FALSE; /* * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES * is not specified. * The pidl functions fail on not existing file names */ if (flags & SHGFI_PIDL) { pidl = ILClone((LPCITEMIDLIST)path); } else if (!(flags & SHGFI_USEFILEATTRIBUTES)) { hr = SHILCreateFromPathW(szFullPath, &pidl, &dwAttributes); } if ((flags & SHGFI_PIDL) || !(flags & SHGFI_USEFILEATTRIBUTES)) { /* get the parent shellfolder */ if (pidl) { hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&pidlLast ); if (SUCCEEDED(hr)) pidlLast = ILClone(pidlLast); ILFree(pidl); } else { ERR("pidl is null!\n"); return FALSE; } } /* get the attributes of the child */ if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES)) { if (!(flags & SHGFI_ATTR_SPECIFIED)) { psfi->dwAttributes = 0xffffffff; } if (psfParent) IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast, &(psfi->dwAttributes) ); } /* get the displayname */ if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME)) { if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { lstrcpyW (psfi->szDisplayName, PathFindFileNameW(szFullPath)); } else { STRRET str; hr = IShellFolder_GetDisplayNameOf( psfParent, pidlLast, SHGDN_INFOLDER, &str); StrRetToStrNW (psfi->szDisplayName, MAX_PATH, &str, pidlLast); } } /* get the type name */ if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME)) { static const WCHAR szFile[] = { 'F','i','l','e',0 }; static const WCHAR szDashFile[] = { '-','f','i','l','e',0 }; if (!(flags & SHGFI_USEFILEATTRIBUTES) || (flags & SHGFI_PIDL)) { char ftype[80]; _ILGetFileType(pidlLast, ftype, 80); MultiByteToWideChar(CP_ACP, 0, ftype, -1, psfi->szTypeName, 80 ); } else { if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) strcatW (psfi->szTypeName, szFile); else { WCHAR sTemp[64]; lstrcpyW(sTemp,PathFindExtensionW(szFullPath)); if (!( HCR_MapTypeToValueW(sTemp, sTemp, 64, TRUE) && HCR_MapTypeToValueW(sTemp, psfi->szTypeName, 80, FALSE ))) { lstrcpynW (psfi->szTypeName, sTemp, 64); strcatW (psfi->szTypeName, szDashFile); } } } } /* ### icons ###*/ Shell_GetImageLists( &big_icons, &small_icons ); if (flags & SHGFI_OPENICON) uGilFlags |= GIL_OPENICON; if (flags & SHGFI_LINKOVERLAY) uGilFlags |= GIL_FORSHORTCUT; else if ((flags&SHGFI_ADDOVERLAYS) || (flags&(SHGFI_ICON|SHGFI_SMALLICON))==SHGFI_ICON) { if (SHELL_IsShortcut(pidlLast)) uGilFlags |= GIL_FORSHORTCUT; } if (flags & SHGFI_OVERLAYINDEX) FIXME("SHGFI_OVERLAYINDEX unhandled\n"); if (flags & SHGFI_SELECTED) FIXME("set icon to selected, stub\n"); if (flags & SHGFI_SHELLICONSIZE) FIXME("set icon to shell size, stub\n"); /* get the iconlocation */ if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION )) { UINT uDummy,uFlags; if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { lstrcpyW(psfi->szDisplayName, swShell32Name); psfi->iIcon = -IDI_SHELL_FOLDER; } else { WCHAR* szExt; static const WCHAR p1W[] = {'%','1',0}; WCHAR sTemp [MAX_PATH]; szExt = PathFindExtensionW(szFullPath); TRACE("szExt=%s\n", debugstr_w(szExt)); if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &psfi->iIcon)) { if (lstrcmpW(p1W, sTemp)) strcpyW(psfi->szDisplayName, sTemp); else { /* the icon is in the file */ strcpyW(psfi->szDisplayName, szFullPath); } } else ret = FALSE; } } else { hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1, (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW, &uDummy, (LPVOID*)&pei); if (SUCCEEDED(hr)) { hr = IExtractIconW_GetIconLocation(pei, uGilFlags, szLocation, MAX_PATH, &iIndex, &uFlags); if (uFlags & GIL_NOTFILENAME) ret = FALSE; else { lstrcpyW (psfi->szDisplayName, szLocation); psfi->iIcon = iIndex; } IExtractIconW_Release(pei); } } } /* get icon index (or load icon)*/ if (SUCCEEDED(hr) && (flags & (SHGFI_ICON | SHGFI_SYSICONINDEX))) { if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { WCHAR sTemp [MAX_PATH]; WCHAR * szExt; int icon_idx=0; lstrcpynW(sTemp, szFullPath, MAX_PATH); if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) psfi->iIcon = SIC_GetIconIndex(swShell32Name, -IDI_SHELL_FOLDER, 0); else { static const WCHAR p1W[] = {'%','1',0}; psfi->iIcon = 0; szExt = PathFindExtensionW(sTemp); if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &icon_idx)) { if (!lstrcmpW(p1W,sTemp)) /* icon is in the file */ strcpyW(sTemp, szFullPath); if (flags & SHGFI_SYSICONINDEX) { psfi->iIcon = SIC_GetIconIndex(sTemp,icon_idx,0); if (psfi->iIcon == -1) psfi->iIcon = 0; } else { UINT ret; if (flags & SHGFI_SMALLICON) ret = PrivateExtractIconsW( sTemp,icon_idx, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), &psfi->hIcon, 0, 1, 0); else ret = PrivateExtractIconsW( sTemp, icon_idx, GetSystemMetrics( SM_CXICON), GetSystemMetrics( SM_CYICON), &psfi->hIcon, 0, 1, 0); if (ret != 0 && ret != (UINT)-1) { IconNotYetLoaded=FALSE; psfi->iIcon = icon_idx; } } } } } else { if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON), uGilFlags, &(psfi->iIcon)))) { ret = FALSE; } } if (ret && (flags & SHGFI_SYSICONINDEX)) { if (flags & SHGFI_SMALLICON) ret = (DWORD_PTR)small_icons; else ret = (DWORD_PTR)big_icons; } } /* icon handle */ if (SUCCEEDED(hr) && (flags & SHGFI_ICON) && IconNotYetLoaded) { if (flags & SHGFI_SMALLICON) psfi->hIcon = ImageList_GetIcon( small_icons, psfi->iIcon, ILD_NORMAL); else psfi->hIcon = ImageList_GetIcon( big_icons, psfi->iIcon, ILD_NORMAL); } if (flags & ~SHGFI_KNOWN_FLAGS) FIXME("unknown flags %08x\n", flags & ~SHGFI_KNOWN_FLAGS); if (psfParent) IShellFolder_Release(psfParent); if (hr != S_OK) ret = FALSE; SHFree(pidlLast); TRACE ("icon=%p index=0x%08x attr=0x%08x name=%s type=%s ret=0x%08lx\n", psfi->hIcon, psfi->iIcon, psfi->dwAttributes, debugstr_w(psfi->szDisplayName), debugstr_w(psfi->szTypeName), ret); return ret; }
bool StringPathAppend(std::wstring* path, const std::wstring& more) { std::unique_ptr<wchar_t[]> buffer(new wchar_t[MAX_PATH]); *path = PathCombineW(buffer.get(), path->c_str(), more.c_str()); return !path->empty(); }
bool StringPathCombine(std::wstring* dest, const std::wstring& path, const std::wstring& more) { std::unique_ptr<wchar_t[]> buffer(new wchar_t[MAX_PATH]); *dest = PathCombineW(buffer.get(), path.c_str(), more.c_str()); return !dest->empty(); }
// 1つ目の引数だけファイルとして扱い、実行する。 // // コマンドは こんな感じで連結されます。 // exe linkpath linkarg cmdarg2 cmdarg3 cmdarg4 ... // static HRESULT HookAndExecute(int show) { int argc = 0; LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); if(!argv) { return HresultFromLastError(); } if(argc <= 1) { char buffer [256]; LoadStringA(GetModuleHandleA(NULL), IDS_USAGE, buffer, 256); MessageBoxA(NULL, buffer ,"gdi++", MB_OK|MB_ICONINFORMATION); LocalFree(argv); return S_OK; } int i; size_t length = 1; for(i=2; i<argc; i++) { length += wcslen(argv[i]) + 3; } LPWSTR cmdline = (WCHAR*)calloc(sizeof(WCHAR), length); if(!cmdline) { LocalFree(argv); return E_OUTOFMEMORY; } LPWSTR p = cmdline; *p = L'\0'; for(i=2; i<argc; i++) { const bool dq = !!wcschr(argv[i], L' '); if (dq) { *p++ = '"'; length--; } StringCchCopyExW(p, length, argv[i], &p, &length, STRSAFE_NO_TRUNCATION); if (dq) { *p++ = '"'; length--; } *p++ = L' '; length--; } *CharPrevW(cmdline, p) = L'\0'; WCHAR file[MAX_PATH], dir[MAX_PATH]; GetCurrentDirectoryW(_countof(dir), dir); StringCchCopyW(file, _countof(file), argv[1]); if(PathIsRelativeW(file)) { PathCombineW(file, dir, file); } else { WCHAR gdippDir[MAX_PATH]; GetModuleFileNameW(NULL, gdippDir, _countof(gdippDir)); PathRemoveFileSpec(gdippDir); // カレントディレクトリがgdi++.exeの置かれているディレクトリと同じだったら、 // 起動しようとしているEXEのフルパスから抜き出したディレクトリ名をカレント // ディレクトリとして起動する。(カレントディレクトリがEXEと同じ場所である // 前提で作られているアプリ対策) if (wcscmp(dir, gdippDir) == 0) { StringCchCopyW(dir, _countof(dir), argv[1]); PathRemoveFileSpec(dir); } } LocalFree(argv); argv = NULL; #ifdef _DEBUG if((GetAsyncKeyState(VK_CONTROL) & 0x8000) && MessageBoxW(NULL, cmdline, NULL, MB_YESNO) != IDYES) { free(cmdline); return NOERROR; } #endif LPITEMIDLIST pidl = NULL; HRESULT hr; //fileのアイテムIDリストを取得 hr = _SHILCreateFromPath(file, &pidl, NULL); if(SUCCEEDED(hr) && pidl) { //SEE_MASK_INVOKEIDLISTを使うと //explorerでクリックして起動したのと同じ動作になる SHELLEXECUTEINFOW sei = { sizeof(SHELLEXECUTEINFOW) }; sei.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_DOENVSUBST | SEE_MASK_WAITFORINPUTIDLE; sei.hwnd = GetDesktopWindow(); sei.lpParameters = cmdline; sei.lpDirectory = dir; sei.nShow = show; sei.lpIDList = pidl; //ShellExecuteExWが内部で呼び出すCreateProcessWをフックして //HookChildProcesses相当の処理を行う DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)ORIG_CreateProcessW, IMPL_CreateProcessW); hr = DetourTransactionCommit(); if(hr == NOERROR) { if(ShellExecuteExW(&sei)) { hr = S_OK; } else { hr = HresultFromLastError(); } } DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)ORIG_CreateProcessW, IMPL_CreateProcessW); DetourTransactionCommit(); } if(pidl) _SHFree(pidl); free(cmdline); return hr; }
// // Searches for files according to the specified Mask starting from the specified Path. // For every file found allocates FILE_DESCW structure and links all theese structures into the FileListHead. // Returns number of files found. // Note: In the ANSI version of FindFirstFile the name is limited to MAX_PATH characters. So we have to use UNICODE version // to completely scan all files. // ULONG FilesScanW( PWCHAR Path, // directory to search in, should be ended with "\" PWCHAR Mask, // search mask PLIST_ENTRY FilesList, // the list where all FILE_DESCW structures will be linked PCRITICAL_SECTION FilesListLock, // file list locking object (OPTIONAL) ULONG SearchPathLen, // the length of the initial search path in chars, used to keep directory structure // relative to the search path ULONG SearchFlags // various flags ) { ULONG Found = 0, PathLen, MaskLen, ScanLen = MAX_PATH; LPWIN32_FIND_DATAW FindData; PWCHAR ScanPath, ResolvedPath = NULL; if (FindData = AppAlloc(sizeof(WIN32_FIND_DATAW))) { if (ResolvedPath = FilesExpandEnvironmentVariablesW(Path)) Path = ResolvedPath; PathLen = wcslen(Path); MaskLen = wcslen(Mask); if (SearchPathLen == 0) SearchPathLen = PathLen; while ((PathLen + MaskLen + 2) > ScanLen) // 1 for "\\" and 1 for "\0" ScanLen += MAX_PATH; if (ScanPath = AppAlloc(ScanLen * sizeof(WCHAR))) { HANDLE hFind; PFILE_DESCW fDesc; memset(FindData, 0, sizeof(WIN32_FIND_DATA)); PathCombineW(ScanPath, Path, Mask); // Searching for files within the current directory first if ((hFind = FindFirstFileW(ScanPath, FindData)) != INVALID_HANDLE_VALUE) { do { if ((FindData->nFileSizeHigh) || (FindData->nFileSizeLow > FILE_SIZE_MAX)) continue; if (FindData->cFileName[0] == '.') continue; if (fDesc = FileDescAlloc(sizeof(FILE_DESCW) + (PathLen + wcslen(Mask) + wcslen(FindData->cFileName) + 2) * sizeof(WCHAR))) { LPWSTR pDir, pPath; wcscpy((PWCHAR)&fDesc->Path, Path); if (pDir = StrRChrW(Mask, NULL, L'\\')) { PathCombineW((PWCHAR)&fDesc->Path, Path, Mask); *PathFindFileNameW((PWCHAR)&fDesc->Path) = 0; pPath = (PWCHAR)&fDesc->Path; } else pPath = Path; PathCombineW((PWCHAR)&fDesc->Path, pPath, FindData->cFileName); fDesc->SearchPathLen = SearchPathLen; fDesc->Flags = SearchFlags; if (FilesListLock) EnterCriticalSection(FilesListLock); InsertTailList(FilesList, &fDesc->Entry); if (FilesListLock) LeaveCriticalSection(FilesListLock); Found += 1; } } while(FindNextFileW(hFind, FindData) && WaitForSingleObject(g_AppShutdownEvent, 0) == WAIT_TIMEOUT); FindClose(hFind); } // if ((hFind = FindFirstFileW(ScanPath, FindData)) != INVALID_HANDLE_VALUE) // Files are searched, looking for directories to scan them recursively PathCombineW(ScanPath, Path, L"*"); if ((hFind = FindFirstFileW(ScanPath, FindData)) != INVALID_HANDLE_VALUE) { do { if (FindData->cFileName[0] != '.' && (FindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { MaskLen = wcslen(FindData->cFileName); if ((PathLen + MaskLen + 2) > ScanLen) // 1 for "\\" and 1 for "\0" { AppFree(ScanPath); do { ScanLen += MAX_PATH; } while ((PathLen + MaskLen + 2) > ScanLen); if (!(ScanPath = AppAlloc(ScanLen * sizeof(WCHAR)))) break; // not enough memory } // if ((PathLen + MaskLen + 2) > ScanLen) PathCombineW(ScanPath, Path, FindData->cFileName); Found += FilesScanW(ScanPath, Mask, FilesList, FilesListLock, SearchPathLen, SearchFlags); } // if (FindData->cFileName[0] != '.' && } while(FindNextFileW(hFind, FindData) && WaitForSingleObject(g_AppShutdownEvent, 0) == WAIT_TIMEOUT); FindClose(hFind); } // if (hFind = FindFirstFileW(ScanPath, FindData)) if (ScanPath) AppFree(ScanPath); } // if (ScanPath = if (ResolvedPath) AppFree(ResolvedPath); AppFree(FindData); } // if (FindData) return(Found); }
// // Copmpletely clears a specified directory removing all files (and subdirectories if ClearSubfolders flag set). // WINERROR FilesClearDirectoryW( LPWSTR pPath, // A full path to deirecroty to clear BOOL bClearSubfolders, // Clear subfolders recursively BOOL bIgnoreErrors // Ignore file delete errors (aka ERROR_SHARING_VIOLATION and so on) ) { WINERROR Status = ERROR_NOT_ENOUGH_MEMORY; PWIN32_FIND_DATAW FindFileData = NULL; LPWSTR pSearchPath = NULL, pFilePath = NULL; HANDLE hFind; ULONG DirPathLen, FilePathLen = MAX_PATH; // chars do // not a loop, used just to break out on error { DirPathLen = (ULONG)lstrlenW(pPath); // chars if (!(pFilePath = AppAlloc(FilePathLen * sizeof(WCHAR)))) { ASSERT(Status == ERROR_NOT_ENOUGH_MEMORY); break; } if (!(pSearchPath = AppAlloc((DirPathLen + cstrlenW(wczFindAll) + 2) * sizeof(WCHAR)))) { ASSERT(Status == ERROR_NOT_ENOUGH_MEMORY); break; } if (!(FindFileData = AppAlloc(sizeof(WIN32_FIND_DATAW)))) { ASSERT(Status == ERROR_NOT_ENOUGH_MEMORY); break; } PathCombineW(pSearchPath, pPath, wczFindAll); hFind = FindFirstFileW(pSearchPath, FindFileData); if (hFind == INVALID_HANDLE_VALUE) { Status = ERROR_PATH_NOT_FOUND; break; } Status = NO_ERROR; do { ULONG NameLen; ULONG PathLen; // Skip "." and ".." names. if (FindFileData->cFileName[0] == '.') continue; NameLen = lstrlenW(FindFileData->cFileName); PathLen = DirPathLen + NameLen + 2; // a char for "\" and one for 0 if (FilePathLen < PathLen) { AppFree(pFilePath); if (!(pFilePath = AppAlloc(PathLen * sizeof(WCHAR)))) { Status = ERROR_NOT_ENOUGH_MEMORY; break; } FilePathLen = PathLen; } PathCombineW(pFilePath, pPath, (LPWSTR)FindFileData->cFileName); if (FindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (bClearSubfolders) { if ((Status = FilesClearDirectoryW(pFilePath, TRUE, bIgnoreErrors)) == NO_ERROR) { if (!RemoveDirectoryW(pFilePath) && !bIgnoreErrors) { Status = GetLastError(); break; } } else break; } // if (ClearSubfolders) } // if (FindFileData->dwFileAttributes & else { if (!DeleteFileW(pFilePath) && !bIgnoreErrors) { Status = GetLastError(); break; } } } while(FindNextFileW(hFind, FindFileData)); } while (FALSE); if (FindFileData) AppFree(FindFileData); if (pSearchPath) AppFree(pSearchPath); if (pFilePath) AppFree(pFilePath); return(Status); }
// combines dir and file name to the full path BOOL FilePathCombineW(LPWSTR dest, const LPWSTR dir, const LPWSTR file) { LPWSTR p = (LPWSTR)file; if(p != NULL)while(*p == '\\' || *p == '/')p++; return PathCombineW(dest, dir, p) == NULL ? FALSE : TRUE; }