Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.1 KiB

  1. //
  2. // Simple wrapper around GetFullPathname and CopyFile that converts to \\? form,
  3. // and also appends leaf file to directory name if necessary.
  4. //
  5. #include "windows.h"
  6. #include <stddef.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <stdarg.h>
  10. #pragma warning(push)
  11. #pragma warning(disable: 4511)
  12. #pragma warning(disable: 4512)
  13. #include "yvals.h"
  14. #pragma warning(disable: 4663)
  15. #pragma warning(pop)
  16. #pragma warning(disable: 4018) /* signed/unsigned mismatch */
  17. #pragma warning(disable: 4290) /* exception specification */
  18. #include <vector>
  19. #include <string.h>
  20. #include <stdarg.h>
  21. #define NUMBER_OF(x) (sizeof(x)/sizeof((x)[0]))
  22. #define FusionpGetLastWin32Error GetLastError
  23. #define FusionpSetLastWin32Error SetLastError
  24. #include <string.h>
  25. #include <stdarg.h>
  26. BOOL
  27. FusionpConvertToBigPath(PCWSTR Path, SIZE_T BufferSize, PWSTR Buffer);
  28. BOOL
  29. FusionpAreWeInOSSetupMode(BOOL* pfIsInSetup) { *pfIsInSetup = FALSE; return TRUE; }
  30. extern "C"
  31. {
  32. BOOL WINAPI SxsDllMain(HINSTANCE hInst, DWORD dwReason, PVOID pvReserved);
  33. void __cdecl wmainCRTStartup();
  34. BOOL FusionpInitializeHeap(HINSTANCE hInstance);
  35. VOID FusionpUninitializeHeap();
  36. };
  37. void ExeEntry()
  38. {
  39. if (!::FusionpInitializeHeap(GetModuleHandleW(NULL)))
  40. goto Exit;
  41. ::wmainCRTStartup();
  42. Exit:
  43. FusionpUninitializeHeap();
  44. }
  45. FILE* g_pLogFile;
  46. const static WCHAR g_pszImage[] = L"copy_bigpath";
  47. void
  48. ReportFailure(
  49. const char* szFormat,
  50. ...
  51. )
  52. {
  53. const DWORD dwLastError = ::GetLastError();
  54. va_list ap;
  55. char rgchBuffer[4096] = { 0 };
  56. WCHAR rgchWin32Error[4096] = { 0 };
  57. va_start(ap, szFormat);
  58. ::_vsnprintf(rgchBuffer, NUMBER_OF(rgchBuffer) - 1, szFormat, ap);
  59. va_end(ap);
  60. if (!::FormatMessageW(
  61. FORMAT_MESSAGE_FROM_SYSTEM,
  62. NULL,
  63. dwLastError,
  64. 0,
  65. rgchWin32Error,
  66. NUMBER_OF(rgchWin32Error) - 1,
  67. &ap))
  68. {
  69. const DWORD dwLastError2 = ::GetLastError();
  70. ::_snwprintf(rgchWin32Error, NUMBER_OF(rgchWin32Error) - 1, L"Error formatting Win32 error %lu\nError from FormatMessage is %lu", dwLastError, dwLastError2);
  71. }
  72. ::fprintf(stderr, "%ls: %s\n%ls\n", g_pszImage, rgchBuffer, rgchWin32Error);
  73. if (g_pLogFile != NULL)
  74. ::fprintf(g_pLogFile, "%ls: %s\n%ls\n", g_pszImage, rgchBuffer, rgchWin32Error);
  75. }
  76. extern "C" int __cdecl wmain(int argc, wchar_t** argv)
  77. {
  78. int iReturnStatus = EXIT_FAILURE;
  79. PWSTR p = NULL;
  80. std::vector<WCHAR> arg1;
  81. std::vector<WCHAR> arg2;
  82. BOOL Success = FALSE;
  83. PCWSTR Leaf = NULL;
  84. ULONG FileAttributes = 0;
  85. DWORD Error = 0;
  86. if (argc != 3)
  87. {
  88. ::fprintf(stderr,
  89. "%ls: Usage:\n"
  90. " %ls <from> <to>\n",
  91. argv[0], argv[0]);
  92. goto Exit;
  93. }
  94. arg1.resize(1UL << 15);
  95. arg2.resize(1UL << 15);
  96. arg1[0] = 0;
  97. arg2[0] = 0;
  98. if (!FusionpConvertToBigPath(argv[1], arg1.size(), &arg1[0]))
  99. goto Exit;
  100. if (!FusionpConvertToBigPath(argv[2], arg2.size(), &arg2[0]))
  101. goto Exit;
  102. arg1.resize(1 + ::wcslen(&arg1[0]));
  103. arg2.resize(1 + ::wcslen(&arg2[0]));
  104. Error = NO_ERROR;
  105. Success = CopyFileW(&arg1[0], &arg2[0], FALSE);
  106. if (!Success
  107. && ((Error = ::FusionpGetLastWin32Error()) == ERROR_ACCESS_DENIED
  108. || Error == ERROR_PATH_NOT_FOUND)
  109. && (FileAttributes = GetFileAttributesW(&arg1[0])) != 0xffffffff
  110. && (FileAttributes = GetFileAttributesW(&arg2[0])) != 0xffffffff
  111. && (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0
  112. && (Leaf = wcsrchr(&arg1[0], '\\')) != NULL
  113. )
  114. {
  115. arg2.insert(arg2.end() - 1, Leaf, arg1.end() - 1);
  116. Success = CopyFileW(&arg1[0], &arg2[0], FALSE);
  117. }
  118. if (!Success && Error != NO_ERROR)
  119. {
  120. ::FusionpSetLastWin32Error(Error);
  121. }
  122. if (!Success)
  123. {
  124. ::ReportFailure("CopyFile\n");
  125. goto Exit;
  126. }
  127. ::printf("%ls -> %ls\n", &arg1[0], &arg2[0]);
  128. iReturnStatus = EXIT_SUCCESS;
  129. Exit:
  130. return iReturnStatus;
  131. }