2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS pending moves operations Information tool
4 * FILE: cmdutils/pendmoves/pendmoves.c
5 * PURPOSE: Query information from registry about pending moves
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
15 BeautifyPath(TCHAR
* Path
, DWORD
* Len
)
17 DWORD LocalLen
= *Len
;
19 /* If there's a ! marking that existing file can be overwritten,
24 if (Path
[0] == _T('!'))
31 /* Remove namespace if prefixed */
34 if (Path
[0] == _T('\\') && Path
[1] == _T('?') &&
35 Path
[2] == _T('?') && Path
[3] == _T('\\'))
42 /* Return modified string + len */
49 DisplayPendingOps(TCHAR
* Value
, DWORD Len
)
51 DWORD Chars
, i
, j
, Count
, SrcLen
, TgtLen
;
52 TCHAR
* SrcFile
, * Target
, * Current
;
54 /* Compute the amount of chars
55 * NULL char isn't relaible EOF (MULTI_SZ)
57 Chars
= Len
/ sizeof(TCHAR
);
62 /* Browse the whole string */
65 /* Jump to the next NULL (end of source) */
66 for (j
= i
; j
< Chars
&& Value
[j
] != 0; ++j
);
67 /* Get len & clean path */
68 SrcLen
= _tcslen(Current
);
69 SrcFile
= BeautifyPath(Current
, &SrcLen
);
70 /* Source file is null - likely the end of the MULTI_SZ, quit */
76 /* Remember position, jump to the begin of the target */
79 /* Update position in MULTI_SZ */
82 /* Jump to the next NULL (end of target) */
83 for (j
= i
; j
< Chars
&& Value
[j
] != 0; ++j
);
84 /* Get len & clean path */
85 TgtLen
= _tcslen(Current
);
86 Target
= BeautifyPath(Current
, &TgtLen
);
87 /* Remember position, jump to the begin of the next source */
93 _ftprintf(stdout
, _T("Source: %s\n"), SrcFile
);
94 /* If is accessible? Warn if not */
95 if (GetFileAttributes(SrcFile
) == INVALID_FILE_ATTRIBUTES
)
97 _ftprintf(stdout
, _T("\t *** Source file lookup error: %d\n"), GetLastError());
99 /* And display target - if empty, it's for deletion, mark as it */
100 _ftprintf(stdout
, _T("Target: %s\n\n"), (_tcslen(Target
) != 0 ? Target
: _T("DELETE")));
102 /* Remember position and number of entries */
112 _tmain(int argc
, const TCHAR
*argv
[])
116 DWORD MaxLen
, Len
, Count
, Type
;
118 FILETIME LastModified
;
119 TCHAR RegistryPath
[] = _T("System\\CurrentControlSet\\Control\\Session Manager");
121 /* Open the SMSS registry key */
122 Ret
= RegOpenKey(HKEY_LOCAL_MACHINE
, RegistryPath
, &hKey
);
123 if (Ret
!= ERROR_SUCCESS
)
125 _ftprintf(stderr
, _T("Failed opening the registry key '%s' (%lx)\n"), RegistryPath
, Ret
);
129 /* Get last modified date + buffer length we need to allocate */
130 Ret
= RegQueryInfoKey(hKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &MaxLen
, NULL
, &LastModified
);
131 if (Ret
!= ERROR_SUCCESS
)
134 _ftprintf(stderr
, _T("Failed querying information for '%s' (%lx)\n"), RegistryPath
, Ret
);
138 /* No value, so no operations */
142 _ftprintf(stdout
, _T("No pending file rename operations registered.\n\n"));
146 /* Allocate memory */
147 Buffer
= HeapAlloc(GetProcessHeap(), 0, MaxLen
);
151 _ftprintf(stderr
, _T("Failed allocating %d bytes\n"), MaxLen
);
155 /* Start with PendingFileRenameOperations */
158 Ret
= RegQueryValueEx(hKey
, _T("PendingFileRenameOperations"), NULL
, &Type
, Buffer
, &Len
);
159 if (Ret
== ERROR_SUCCESS
&& Type
== REG_MULTI_SZ
)
161 Count
+= DisplayPendingOps(Buffer
, Len
);
164 /* Continue with PendingFileRenameOperations2 - used if PendingFileRenameOperations is too big */
166 Ret
= RegQueryValueEx(hKey
, _T("PendingFileRenameOperations2"), NULL
, &Type
, Buffer
, &Len
);
167 if (Ret
== ERROR_SUCCESS
&& Type
== REG_MULTI_SZ
)
169 Count
+= DisplayPendingOps(Buffer
, Len
);
172 /* Release everything */
173 HeapFree(GetProcessHeap(), 0, Buffer
);
176 /* If we found entries, display modification date */
182 /* Convert our UTC time to local time, and then to system time to allow easy display */
183 if (FileTimeToLocalFileTime(&LastModified
, &LocalTime
) && FileTimeToSystemTime(&LocalTime
, &SysTime
))
185 _ftprintf(stdout
, _T("Time of last update to pending moves key: %02d/%02d/%04d %02d:%02d\n\n"),
186 SysTime
.wDay
, SysTime
.wMonth
, SysTime
.wYear
, SysTime
.wHour
, SysTime
.wMinute
);
189 /* No operations found */
192 _ftprintf(stdout
, _T("No pending file rename operations registered.\n\n"));