+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS pending moves operations Information tool
- * FILE: cmdutils/pendmoves/pendmoves.c
- * PURPOSE: Query information from registry about pending moves
- * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
- */
-
-#include <windows.h>
-#include <tchar.h>
-#include <stdio.h>
-
-static
-TCHAR *
-BeautifyPath(TCHAR * Path, DWORD * Len)
-{
- DWORD LocalLen = *Len;
-
- /* If there's a ! marking that existing file can be overwritten,
- * drop it
- */
- if (LocalLen > 1)
- {
- if (Path[0] == _T('!'))
- {
- ++Path;
- --LocalLen;
- }
- }
-
- /* Remove namespace if prefixed */
- if (LocalLen > 4)
- {
- if (Path[0] == _T('\\') && Path[1] == _T('?') &&
- Path[2] == _T('?') && Path[3] == _T('\\'))
- {
- Path += 4;
- LocalLen -= 4;
- }
- }
-
- /* Return modified string + len */
- *Len = LocalLen;
- return Path;
-}
-
-static
-DWORD
-DisplayPendingOps(TCHAR * Value, DWORD Len)
-{
- DWORD Chars, i, j, Count, SrcLen, TgtLen;
- TCHAR * SrcFile, * Target, * Current;
-
- /* Compute the amount of chars
- * NULL char isn't relaible EOF (MULTI_SZ)
- */
- Chars = Len / sizeof(TCHAR);
-
- i = 0;
- Count = 0;
- Current = Value;
- /* Browse the whole string */
- while (i < Chars)
- {
- /* Jump to the next NULL (end of source) */
- for (j = i; j < Chars && Value[j] != 0; ++j);
- /* Get len & clean path */
- SrcLen = _tcslen(Current);
- SrcFile = BeautifyPath(Current, &SrcLen);
- /* Source file is null - likely the end of the MULTI_SZ, quit */
- if (SrcLen == 0)
- {
- break;
- }
-
- /* Remember position, jump to the begin of the target */
- i = j;
- ++i;
- /* Update position in MULTI_SZ */
- Current = Value + i;
-
- /* Jump to the next NULL (end of target) */
- for (j = i; j < Chars && Value[j] != 0; ++j);
- /* Get len & clean path */
- TgtLen = _tcslen(Current);
- Target = BeautifyPath(Current, &TgtLen);
- /* Remember position, jump to the begin of the next source */
- i = j;
- ++i;
- Current = Value + i;
-
- /* Display source */
- _ftprintf(stdout, _T("Source: %s\n"), SrcFile);
- /* If is accessible? Warn if not */
- if (GetFileAttributes(SrcFile) == INVALID_FILE_ATTRIBUTES)
- {
- _ftprintf(stdout, _T("\t *** Source file lookup error: %d\n"), GetLastError());
- }
- /* And display target - if empty, it's for deletion, mark as it */
- _ftprintf(stdout, _T("Target: %s\n\n"), (_tcslen(Target) != 0 ? Target: _T("DELETE")));
-
- /* Remember position and number of entries */
- Current = Value + i;
- ++Count;
- }
-
- return Count;
-}
-
-int
-__cdecl
-_tmain(int argc, const TCHAR *argv[])
-{
- HKEY hKey;
- LONG Ret;
- DWORD MaxLen, Len, Count, Type;
- PVOID Buffer;
- FILETIME LastModified;
- TCHAR RegistryPath[] = _T("System\\CurrentControlSet\\Control\\Session Manager");
-
- /* Open the SMSS registry key */
- Ret = RegOpenKey(HKEY_LOCAL_MACHINE, RegistryPath, &hKey);
- if (Ret != ERROR_SUCCESS)
- {
- _ftprintf(stderr, _T("Failed opening the registry key '%s' (%lx)\n"), RegistryPath, Ret);
- return 1;
- }
-
- /* Get last modified date + buffer length we need to allocate */
- Ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &MaxLen, NULL, &LastModified);
- if (Ret != ERROR_SUCCESS)
- {
- RegCloseKey(hKey);
- _ftprintf(stderr, _T("Failed querying information for '%s' (%lx)\n"), RegistryPath, Ret);
- return 1;
- }
-
- /* No value, so no operations */
- if (MaxLen == 0)
- {
- RegCloseKey(hKey);
- _ftprintf(stdout, _T("No pending file rename operations registered.\n\n"));
- return 0;
- }
-
- /* Allocate memory */
- Buffer = HeapAlloc(GetProcessHeap(), 0, MaxLen);
- if (Buffer == NULL)
- {
- RegCloseKey(hKey);
- _ftprintf(stderr, _T("Failed allocating %d bytes\n"), MaxLen);
- return 1;
- }
-
- /* Start with PendingFileRenameOperations */
- Count = 0;
- Len = MaxLen;
- Ret = RegQueryValueEx(hKey, _T("PendingFileRenameOperations"), NULL, &Type, Buffer, &Len);
- if (Ret == ERROR_SUCCESS && Type == REG_MULTI_SZ)
- {
- Count += DisplayPendingOps(Buffer, Len);
- }
-
- /* Continue with PendingFileRenameOperations2 - used if PendingFileRenameOperations is too big */
- Len = MaxLen;
- Ret = RegQueryValueEx(hKey, _T("PendingFileRenameOperations2"), NULL, &Type, Buffer, &Len);
- if (Ret == ERROR_SUCCESS && Type == REG_MULTI_SZ)
- {
- Count += DisplayPendingOps(Buffer, Len);
- }
-
- /* Release everything */
- HeapFree(GetProcessHeap(), 0, Buffer);
- RegCloseKey(hKey);
-
- /* If we found entries, display modification date */
- if (Count != 0)
- {
- FILETIME LocalTime;
- SYSTEMTIME SysTime;
-
- /* Convert our UTC time to local time, and then to system time to allow easy display */
- if (FileTimeToLocalFileTime(&LastModified, &LocalTime) && FileTimeToSystemTime(&LocalTime, &SysTime))
- {
- _ftprintf(stdout, _T("Time of last update to pending moves key: %02d/%02d/%04d %02d:%02d\n\n"),
- SysTime.wDay, SysTime.wMonth, SysTime.wYear, SysTime.wHour, SysTime.wMinute);
- }
- }
- /* No operations found */
- else
- {
- _ftprintf(stdout, _T("No pending file rename operations registered.\n\n"));
- }
-
- return 0;
-}