/** * Determines if the file system for the specified file handle is local * @param file path to check the filesystem type for, must be at most MAX_PATH * @param isLocal out parameter which will hold TRUE if the drive is local * @return TRUE if the call succeeded */ BOOL IsLocalFile(LPCWSTR file, BOOL &isLocal) { WCHAR rootPath[MAX_PATH + 1] = { L'\0' }; if (wcslen(file) > MAX_PATH) { return FALSE; } wcsncpy(rootPath, file, MAX_PATH); PathStripToRootW(rootPath); isLocal = GetDriveTypeW(rootPath) == DRIVE_FIXED; return TRUE; }
static UINT msi_change_media( MSIPACKAGE *package, struct media_info *mi ) { LPSTR msg; LPWSTR error, error_dialog; LPWSTR source_dir; UINT r = ERROR_SUCCESS; static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0}; static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0}; if ( (msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE && !gUIHandlerA ) return ERROR_SUCCESS; error = generate_error_string( package, 1302, 1, mi->disk_prompt ); error_dialog = msi_dup_property( package, error_prop ); source_dir = msi_dup_property( package, cszSourceDir ); PathStripToRootW(source_dir); while ( r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir) ) { r = msi_spawn_error_dialog( package, error_dialog, error ); if (gUIHandlerA) { msg = strdupWtoA( error ); gUIHandlerA( gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg ); msi_free(msg); } } msi_free( error ); msi_free( error_dialog ); msi_free( source_dir ); return r; }
UINT WINAPI SHExplorerParseCmdLine(ExplorerCommandLineParseResults * pInfo) { WCHAR strField[MAX_PATH]; WCHAR strDir[MAX_PATH]; PCWSTR strCmdLine = GetCommandLineW(); PCWSTR strFieldArray = PathGetArgsW(strCmdLine); if (!*strFieldArray) { pInfo->dwFlags = 9; pInfo->pidlPath = _GetDocumentsPidl(); if (!pInfo->pidlPath) { GetWindowsDirectoryW(strDir, MAX_PATH); PathStripToRootW(strDir); pInfo->pidlPath = ILCreateFromPathW(strDir); } return (LONG) (pInfo->pidlPath); } PCWSTR strNextArg = _FindFirstField(strFieldArray); BOOL hasNext = TRUE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); while (TRUE) { // Basic flags-only params first if (!StrCmpIW(strField, L"/N")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_N | SH_EXPLORER_CMDLINE_FLAG_ONE; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/S")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_S; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/E")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_E; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/SELECT")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SELECT; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/NOUI")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_NOUI; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"-embedding")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_EMBED; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/SEPARATE")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SEPARATE; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/INPROC")) { // No idea what Inproc is supposed to do, but it gets a GUID, and parses it. TRACE("CmdLine Parser: Found %S flag\n", strField); if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); if (!GUIDFromStringW(strField, &(pInfo->guidInproc))) return FALSE; pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_INPROC; TRACE("CmdLine Parser: Parsed /INPROC flag. dwFlags=%08lx, guidInproc=%S\n", pInfo->dwFlags, strField); } else if (!StrCmpIW(strField, L"/ROOT")) { LPITEMIDLIST pidlRoot = NULL; // The window should be rooted TRACE("CmdLine Parser: Found %S flag\n", strField); if (!pInfo->pidlPath) return FALSE; if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); // Root may be a pidl if (!StrCmpIW(strField, L"/IDLIST")) { if (hasNext) { hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); } pidlRoot = _ILReadFromSharedMemory(strField); } else { // Or just a path string _ParsePathToPidl(strField, &pidlRoot); } pInfo->pidlRoot = pidlRoot; // The root defaults to the desktop if (!pidlRoot) { if (FAILED(SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &(pInfo->pidlRoot)))) pInfo->pidlRoot = NULL; } // TODO: Create rooted PIDL from pInfo->pidlPath and pInfo->pidlRoot TRACE("CmdLine Parser: Parsed /ROOT flag. dwFlags=%08lx, pidlRoot=%p\n", pInfo->dwFlags, pInfo->pidlRoot); } else { // Anything else is part of the target path to browse to TRACE("CmdLine Parser: Found target path %S\n", strField); // Which can be a shared-memory itemidlist if (!StrCmpIW(strField, L"/IDLIST")) { LPITEMIDLIST pidlArg; if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); pidlArg = _ILReadFromSharedMemory(strField); if (!pidlArg) return FALSE; if (pInfo->pidlPath) ILFree(pInfo->pidlPath); pInfo->pidlPath = pidlArg; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath); } else { // Or just a plain old string. WCHAR szPath[MAX_PATH]; DWORD result = GetFullPathNameW(strField, _countof(szPath), szPath, NULL); if (result != 0 && result <= _countof(szPath) && PathFileExistsW(szPath)) StringCchCopyW(strField, _countof(strField), szPath); LPITEMIDLIST pidlPath = ILCreateFromPathW(strField); pInfo->pidlPath = pidlPath; if (pidlPath) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_IDLIST; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath); } else { // The path could not be parsed into an ID List, // so pass it on as a plain string. PWSTR field = StrDupW(strField); pInfo->strPath = field; if (field) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_STRING; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, strPath=%S\n", pInfo->dwFlags, field); } } } } if (!hasNext) break; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); } return TRUE; }
static UINT load_media_info(MSIPACKAGE *package, MSIFILE *file, struct media_info *mi) { MSIRECORD *row; LPWSTR source_dir; LPWSTR source; DWORD options; UINT r; static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=', ' ','%','i',' ','A','N','D',' ','`','D','i','s','k','I','d','`',' ','>','=', ' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ', '`','D','i','s','k','I','d','`',0 }; row = MSI_QueryGetRecord(package->db, query, file->Sequence, mi->disk_id); if (!row) { TRACE("Unable to query row\n"); return ERROR_FUNCTION_FAILED; } mi->is_extracted = FALSE; mi->disk_id = MSI_RecordGetInteger(row, 1); mi->last_sequence = MSI_RecordGetInteger(row, 2); msi_free(mi->disk_prompt); mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3)); msi_free(mi->cabinet); mi->cabinet = strdupW(MSI_RecordGetString(row, 4)); msi_free(mi->volume_label); mi->volume_label = strdupW(MSI_RecordGetString(row, 5)); msiobj_release(&row->hdr); if (!mi->first_volume) mi->first_volume = strdupW(mi->volume_label); source_dir = msi_dup_property(package, cszSourceDir); lstrcpyW(mi->source, source_dir); PathStripToRootW(source_dir); mi->type = GetDriveTypeW(source_dir); if (file->IsCompressed && mi->cabinet) { if (mi->cabinet[0] == '#') { r = writeout_cabinet_stream(package, &mi->cabinet[1], mi->source); if (r != ERROR_SUCCESS) { ERR("Failed to extract cabinet stream\n"); return ERROR_FUNCTION_FAILED; } } else lstrcatW(mi->source, mi->cabinet); } options = MSICODE_PRODUCT; if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) { source = source_dir; options |= MSISOURCETYPE_MEDIA; } else if (package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL)) { source = package->BaseURL; options |= MSISOURCETYPE_URL; } else { source = mi->source; options |= MSISOURCETYPE_NETWORK; } if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) msi_package_add_media_disk(package, package->Context, MSICODE_PRODUCT, mi->disk_id, mi->volume_label, mi->disk_prompt); msi_package_add_info(package, package->Context, options, INSTALLPROPERTY_LASTUSEDSOURCEW, source); msi_free(source_dir); return ERROR_SUCCESS; }
/** * Tests whether a file can be trashed * @param wszPath Path to the file to be trash * @returns TRUE if the file can be trashed, FALSE otherwise */ BOOL TRASH_CanTrashFile(LPCWSTR wszPath) { LONG ret; DWORD dwNukeOnDelete, dwType, VolSerialNumber, MaxComponentLength; DWORD FileSystemFlags, dwSize, dwDisposition; HKEY hKey; WCHAR szBuffer[10]; WCHAR szKey[150] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume\\"; if (wszPath[1] != L':') { /* path is UNC */ return FALSE; } // Copy and retrieve the root path from get given string WCHAR wszRootPathName[MAX_PATH]; StringCbCopy(wszRootPathName, sizeof(wszRootPathName), wszPath); PathStripToRootW(wszRootPathName); // Test to see if the drive is fixed (non removable) if (GetDriveTypeW(wszRootPathName) != DRIVE_FIXED) { /* no bitbucket on removable media */ return FALSE; } if (!GetVolumeInformationW(wszRootPathName, NULL, 0, &VolSerialNumber, &MaxComponentLength, &FileSystemFlags, NULL, 0)) { ERR("GetVolumeInformationW failed with %u wszRootPathName=%s\n", GetLastError(), debugstr_w(wszRootPathName)); return FALSE; } swprintf(szBuffer, L"%04X-%04X", LOWORD(VolSerialNumber), HIWORD(VolSerialNumber)); wcscat(szKey, szBuffer); if (RegCreateKeyExW(HKEY_CURRENT_USER, szKey, 0, NULL, 0, KEY_WRITE, NULL, &hKey, &dwDisposition) != ERROR_SUCCESS) { ERR("RegCreateKeyExW failed\n"); return FALSE; } if (dwDisposition & REG_CREATED_NEW_KEY) { /* per default move to bitbucket */ dwNukeOnDelete = 0; RegSetValueExW(hKey, L"NukeOnDelete", 0, REG_DWORD, (LPBYTE)&dwNukeOnDelete, sizeof(DWORD)); /* per default unlimited size */ dwSize = -1; RegSetValueExW(hKey, L"MaxCapacity", 0, REG_DWORD, (LPBYTE)&dwSize, sizeof(DWORD)); RegCloseKey(hKey); return TRUE; } else { dwSize = sizeof(dwNukeOnDelete); ret = RegQueryValueExW(hKey, L"NukeOnDelete", NULL, &dwType, (LPBYTE)&dwNukeOnDelete, &dwSize); if (ret != ERROR_SUCCESS) { if (ret == ERROR_FILE_NOT_FOUND) { /* restore key and enable bitbucket */ dwNukeOnDelete = 0; RegSetValueExW(hKey, L"NukeOnDelete", 0, REG_DWORD, (LPBYTE)&dwNukeOnDelete, sizeof(DWORD)); } RegCloseKey(hKey); return TRUE; } else if (dwNukeOnDelete) { /* do not delete to bitbucket */ RegCloseKey(hKey); return FALSE; } /* FIXME * check if bitbucket is full */ RegCloseKey(hKey); return TRUE; } }
/************************************************************************* * PathStripToRoot [SHELL32.50] */ BOOL WINAPI PathStripToRootAW(LPVOID lpszPath) { if (SHELL_OsIsUnicode()) return PathStripToRootW(lpszPath); return PathStripToRootA(lpszPath); }