| 1 | #include "ViewLog.h" |
| 2 | |
| 3 | HRESULT ViewLog(LogAction log, int nCmdShow, BOOL showErrors) { |
| 4 | if (log < 0 || log > LogActionWindowsUpdate) { |
| 5 | return E_INVALIDARG; |
| 6 | } |
| 7 | |
| 8 | WCHAR workDir[MAX_PATH]; |
| 9 | |
| 10 | switch (log) { |
| 11 | case LogActionSystem: { |
| 12 | LPCWSTR logsPath = AtLeastWinVista() ? L"%SystemRoot%\\Logs" : L"%SystemRoot%\\Temp"; |
| 13 | ExpandEnvironmentStrings(logsPath, workDir, ARRAYSIZE(workDir)); |
| 14 | break; |
| 15 | } |
| 16 | |
| 17 | case LogActionLocal: { |
| 18 | GetTempPath(ARRAYSIZE(workDir), workDir); |
| 19 | break; |
| 20 | } |
| 21 | |
| 22 | case LogActionLocalLow: { |
| 23 | if (!AtLeastWinVista()) { |
| 24 | return HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION); |
| 25 | } |
| 26 | |
| 27 | if (AtLeastWin7()) { |
| 28 | // AppData\Low\Temp |
| 29 | typedef HRESULT (*_SHGetKnownFolderPath)(const KNOWNFOLDERID *rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); |
| 30 | _SHGetKnownFolderPath $SHGetKnownFolderPath = (_SHGetKnownFolderPath)GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetKnownFolderPath"); |
| 31 | if ($SHGetKnownFolderPath == NULL) { |
| 32 | return HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION); |
| 33 | } |
| 34 | |
| 35 | LPWSTR localLow; |
| 36 | HRESULT hr = $SHGetKnownFolderPath(&FOLDERID_LocalAppDataLow, CSIDL_FLAG_CREATE, NULL, &localLow); |
| 37 | CHECK_HR_OR_RETURN(L"SHGetKnownFolderPath"); |
| 38 | |
| 39 | StringCchPrintf(workDir, ARRAYSIZE(workDir), L"%ls\\Temp", localLow); |
| 40 | LocalFree(localLow); |
| 41 | } else { |
| 42 | // AppData\Local\Temp\Low |
| 43 | WCHAR localTemp[MAX_PATH]; |
| 44 | GetTempPath(ARRAYSIZE(localTemp), localTemp); |
| 45 | StringCchPrintf(workDir, ARRAYSIZE(workDir), L"%ls\\Low", localTemp); |
| 46 | } |
| 47 | break; |
| 48 | } |
| 49 | |
| 50 | case LogActionWindowsUpdate: { |
| 51 | HRESULT hr = SHGetFolderPath(0, CSIDL_WINDOWS, NULL, 0, workDir); |
| 52 | CHECK_HR_OR_RETURN(L"SHGetFolderPath"); |
| 53 | |
| 54 | if (AtLeastWin10()) { |
| 55 | // Windows 10 moves WU/USO logs to ETW. The ETW logs can be converted back to a plain-text .log using a cmdlet. |
| 56 | WCHAR powershell[MAX_PATH]; |
| 57 | ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", powershell, ARRAYSIZE(powershell)); |
| 58 | |
| 59 | DWORD code = 0; |
| 60 | hr = Exec(NULL, powershell, L"-NoProfile -Command Get-WindowsUpdateLog", workDir, nCmdShow, TRUE, &code); |
no test coverage detected