/* FIXME: search NETWORK and URL sources as well */ static UINT find_published_source(MSIPACKAGE *package, struct media_info *mi) { WCHAR source[MAX_PATH]; WCHAR volume[MAX_PATH]; WCHAR prompt[MAX_PATH]; DWORD volumesz, promptsz; DWORD index, size, id; UINT r; r = MsiSourceListGetInfoW(package->ProductCode, NULL, package->Context, MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, source, &size); if (r != ERROR_SUCCESS) return r; index = 0; volumesz = MAX_PATH; promptsz = MAX_PATH; while (MsiSourceListEnumMediaDisksW(package->ProductCode, NULL, package->Context, MSICODE_PRODUCT, index++, &id, volume, &volumesz, prompt, &promptsz) == ERROR_SUCCESS) { mi->disk_id = id; mi->volume_label = msi_realloc(mi->volume_label, ++volumesz * sizeof(WCHAR)); lstrcpyW(mi->volume_label, volume); mi->disk_prompt = msi_realloc(mi->disk_prompt, ++promptsz * sizeof(WCHAR)); lstrcpyW(mi->disk_prompt, prompt); if (source_matches_volume(mi, source)) { /* FIXME: what about SourceDir */ lstrcpyW(mi->source, source); lstrcatW(mi->source, mi->cabinet); return ERROR_SUCCESS; } } return ERROR_FUNCTION_FAILED; }
static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, LPCWSTR path, int depth, LPWSTR *appValue) { UINT rc; DWORD attr; LPWSTR val = NULL; TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth, appValue); if (ACTION_IsFullPath(path)) { if (sig->File) rc = ACTION_RecurseSearchDirectory(package, &val, sig, path, depth); else { /* Recursively searching a directory makes no sense when the * directory to search is the thing you're trying to find. */ rc = ACTION_CheckDirectory(package, path, &val); } } else { WCHAR pathWithDrive[MAX_PATH] = { 'C',':','\\',0 }; DWORD drives = GetLogicalDrives(); int i; rc = ERROR_SUCCESS; for (i = 0; rc == ERROR_SUCCESS && !val && i < 26; i++) { if (!(drives & (1 << i))) continue; pathWithDrive[0] = 'A' + i; if (GetDriveTypeW(pathWithDrive) != DRIVE_FIXED) continue; lstrcpynW(pathWithDrive + 3, path, sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3); if (sig->File) rc = ACTION_RecurseSearchDirectory(package, &val, sig, pathWithDrive, depth); else rc = ACTION_CheckDirectory(package, pathWithDrive, &val); } } attr = GetFileAttributesW(val); if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) && val && val[lstrlenW(val) - 1] != '\\') { val = msi_realloc(val, (lstrlenW(val) + 2) * sizeof(WCHAR)); if (!val) rc = ERROR_OUTOFMEMORY; else PathAddBackslashW(val); } *appValue = val; TRACE("returning %d\n", rc); return rc; }