summaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/file2utl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/file2utl.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/file2utl.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/file2utl.cpp b/src/libs/dutil/WixToolset.DUtil/file2utl.cpp
new file mode 100644
index 00000000..88f8377c
--- /dev/null
+++ b/src/libs/dutil/WixToolset.DUtil/file2utl.cpp
@@ -0,0 +1,164 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5
6// Exit macros
7#define FileExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_FILEUTIL, x, s, __VA_ARGS__)
8#define FileExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_FILEUTIL, x, s, __VA_ARGS__)
9#define FileExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_FILEUTIL, x, s, __VA_ARGS__)
10#define FileExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_FILEUTIL, x, s, __VA_ARGS__)
11#define FileExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_FILEUTIL, x, s, __VA_ARGS__)
12#define FileExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_FILEUTIL, x, s, __VA_ARGS__)
13#define FileExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_FILEUTIL, p, x, e, s, __VA_ARGS__)
14#define FileExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_FILEUTIL, p, x, s, __VA_ARGS__)
15#define FileExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_FILEUTIL, p, x, e, s, __VA_ARGS__)
16#define FileExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_FILEUTIL, p, x, s, __VA_ARGS__)
17#define FileExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_FILEUTIL, e, x, s, __VA_ARGS__)
18#define FileExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_FILEUTIL, g, x, s, __VA_ARGS__)
19
20// constants
21
22const LPCWSTR REGISTRY_PENDING_FILE_RENAME_KEY = L"SYSTEM\\CurrentControlSet\\Control\\Session Manager";
23const LPCWSTR REGISTRY_PENDING_FILE_RENAME_VALUE = L"PendingFileRenameOperations";
24
25
26/*******************************************************************
27 FileExistsAfterRestart - checks that a file exists and will continue
28 to exist after restart.
29
30********************************************************************/
31extern "C" BOOL DAPI FileExistsAfterRestart(
32 __in_z LPCWSTR wzPath,
33 __out_opt DWORD *pdwAttributes
34 )
35{
36 HRESULT hr = S_OK;
37 BOOL fExists = FALSE;
38 HKEY hkPendingFileRename = NULL;
39 LPWSTR* rgsczRenames = NULL;
40 DWORD cRenames = 0;
41 BOOL fPathEqual = FALSE;
42
43 fExists = FileExistsEx(wzPath, pdwAttributes);
44 if (fExists)
45 {
46 hr = RegOpen(HKEY_LOCAL_MACHINE, REGISTRY_PENDING_FILE_RENAME_KEY, KEY_QUERY_VALUE, &hkPendingFileRename);
47 if (E_FILENOTFOUND == hr)
48 {
49 ExitFunction1(hr = S_OK);
50 }
51 FileExitOnFailure(hr, "Failed to open pending file rename registry key.");
52
53 hr = RegReadStringArray(hkPendingFileRename, REGISTRY_PENDING_FILE_RENAME_VALUE, &rgsczRenames, &cRenames);
54 if (E_FILENOTFOUND == hr)
55 {
56 ExitFunction1(hr = S_OK);
57 }
58 FileExitOnFailure(hr, "Failed to read pending file renames.");
59
60 // The pending file renames array is pairs of source and target paths. We only care
61 // about checking the source paths so skip the target paths (i += 2).
62 for (DWORD i = 0; i < cRenames; i += 2)
63 {
64 LPWSTR wzRename = rgsczRenames[i];
65 if (wzRename && *wzRename)
66 {
67 hr = PathCompareCanonicalized(wzPath, wzRename, &fPathEqual);
68 FileExitOnFailure(hr, "Failed to compare path from pending file rename to check path.");
69
70 if (fPathEqual)
71 {
72 fExists = FALSE;
73 break;
74 }
75 }
76 }
77 }
78
79LExit:
80 ReleaseStrArray(rgsczRenames, cRenames);
81 ReleaseRegKey(hkPendingFileRename);
82
83 return fExists;
84}
85
86
87/*******************************************************************
88 FileRemoveFromPendingRename - removes the file path from the pending
89 file rename list.
90
91********************************************************************/
92extern "C" HRESULT DAPI FileRemoveFromPendingRename(
93 __in_z LPCWSTR wzPath
94 )
95{
96 HRESULT hr = S_OK;
97 HKEY hkPendingFileRename = NULL;
98 LPWSTR* rgsczRenames = NULL;
99 DWORD cRenames = 0;
100 BOOL fPathEqual = FALSE;
101 BOOL fRemoved = FALSE;
102 DWORD cNewRenames = 0;
103
104 hr = RegOpen(HKEY_LOCAL_MACHINE, REGISTRY_PENDING_FILE_RENAME_KEY, KEY_QUERY_VALUE | KEY_SET_VALUE, &hkPendingFileRename);
105 if (E_FILENOTFOUND == hr)
106 {
107 ExitFunction1(hr = S_OK);
108 }
109 FileExitOnFailure(hr, "Failed to open pending file rename registry key.");
110
111 hr = RegReadStringArray(hkPendingFileRename, REGISTRY_PENDING_FILE_RENAME_VALUE, &rgsczRenames, &cRenames);
112 if (E_FILENOTFOUND == hr)
113 {
114 ExitFunction1(hr = S_OK);
115 }
116 FileExitOnFailure(hr, "Failed to read pending file renames.");
117
118 // The pending file renames array is pairs of source and target paths. We only care
119 // about checking the source paths so skip the target paths (i += 2).
120 for (DWORD i = 0; i < cRenames; i += 2)
121 {
122 LPWSTR wzRename = rgsczRenames[i];
123 if (wzRename && *wzRename)
124 {
125 hr = PathCompareCanonicalized(wzPath, wzRename, &fPathEqual);
126 FileExitOnFailure(hr, "Failed to compare path from pending file rename to check path.");
127
128 // If we find our path in the list, null out the source and target slot and
129 // we'll compact the array next.
130 if (fPathEqual)
131 {
132 ReleaseNullStr(rgsczRenames[i]);
133 ReleaseNullStr(rgsczRenames[i + 1]);
134 fRemoved = TRUE;
135 }
136 }
137 }
138
139 if (fRemoved)
140 {
141 // Compact the array by removing any nulls.
142 for (DWORD i = 0; i < cRenames; ++i)
143 {
144 LPWSTR wzRename = rgsczRenames[i];
145 if (wzRename)
146 {
147 rgsczRenames[cNewRenames] = wzRename;
148 ++cNewRenames;
149 }
150 }
151
152 cRenames = cNewRenames; // ignore the pointers on the end of the array since an early index points to them already.
153
154 // Write the new array back to the pending file rename key.
155 hr = RegWriteStringArray(hkPendingFileRename, REGISTRY_PENDING_FILE_RENAME_VALUE, rgsczRenames, cRenames);
156 FileExitOnFailure(hr, "Failed to update pending file renames.");
157 }
158
159LExit:
160 ReleaseStrArray(rgsczRenames, cRenames);
161 ReleaseRegKey(hkPendingFileRename);
162
163 return hr;
164}