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.

141 lines
3.9 KiB

  1. //
  2. // Simple wrapper around GetFullPathname and CreateDirectory that converts to \\? form,
  3. // and creates multiple levels.
  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. #include <vector>
  16. #pragma warning(pop)
  17. #include <string.h>
  18. #include <stdarg.h>
  19. #define NUMBER_OF(x) (sizeof(x)/sizeof((x)[0]))
  20. #define FusionpGetLastWin32Error GetLastError
  21. #define FusionpSetLastWin32Error SetLastError
  22. #include <string.h>
  23. #include <stdarg.h>
  24. BOOL FusionpConvertToBigPath(PCWSTR Path, SIZE_T BufferSize, PWSTR Buffer);
  25. BOOL FusionpSkipBigPathRoot(PCWSTR s, OUT SIZE_T*);
  26. BOOL FusionpAreWeInOSSetupMode(BOOL* pfIsInSetup) { *pfIsInSetup = FALSE; return TRUE; }
  27. extern "C"
  28. {
  29. BOOL WINAPI SxsDllMain(HINSTANCE hInst, DWORD dwReason, PVOID pvReserved);
  30. void __cdecl wmainCRTStartup();
  31. BOOL FusionpInitializeHeap(HINSTANCE hInstance);
  32. VOID FusionpUninitializeHeap();
  33. };
  34. void ExeEntry()
  35. {
  36. if (!::FusionpInitializeHeap(GetModuleHandleW(NULL)))
  37. goto Exit;
  38. ::wmainCRTStartup();
  39. Exit:
  40. FusionpUninitializeHeap();
  41. }
  42. FILE* g_pLogFile;
  43. const static WCHAR g_pszImage[] = L"mkdir_bigpath";
  44. void
  45. ReportFailure(
  46. const char* szFormat,
  47. ...
  48. )
  49. {
  50. const DWORD dwLastError = ::GetLastError();
  51. va_list ap;
  52. char rgchBuffer[4096] = { 0 };
  53. WCHAR rgchWin32Error[4096] = { 0 };
  54. va_start(ap, szFormat);
  55. _vsnprintf(rgchBuffer, NUMBER_OF(rgchBuffer) - 1, szFormat, ap);
  56. va_end(ap);
  57. if (!::FormatMessageW(
  58. FORMAT_MESSAGE_FROM_SYSTEM,
  59. NULL,
  60. dwLastError,
  61. 0,
  62. rgchWin32Error,
  63. NUMBER_OF(rgchWin32Error),
  64. &ap))
  65. {
  66. const DWORD dwLastError2 = ::GetLastError();
  67. _snwprintf(rgchWin32Error, NUMBER_OF(rgchWin32Error) - 1, L"Error formatting Win32 error %lu\nError from FormatMessage is %lu", dwLastError, dwLastError2);
  68. }
  69. fprintf(stderr, "%ls: %s\n%ls\n", g_pszImage, rgchBuffer, rgchWin32Error);
  70. if (g_pLogFile != NULL)
  71. fprintf(g_pLogFile, "%ls: %s\n%ls\n", g_pszImage, rgchBuffer, rgchWin32Error);
  72. }
  73. extern "C" int __cdecl wmain(int argc, wchar_t** argv)
  74. {
  75. int iReturnStatus = EXIT_FAILURE;
  76. std::vector<WCHAR> arg1;
  77. PWSTR p = NULL;
  78. SIZE_T i = 0;
  79. if (argc != 2)
  80. {
  81. fprintf(stderr,
  82. "%ls: Usage:\n"
  83. " %ls <directory-to-create>\n",
  84. argv[0], argv[0]);
  85. goto Exit;
  86. }
  87. arg1.resize(1 + (1UL << 15));
  88. arg1[0] = 0;
  89. if (!FusionpConvertToBigPath(argv[1], arg1.size(), &arg1[0]))
  90. {
  91. ::ReportFailure("FusionpConvertToBigPath\n");
  92. goto Exit;
  93. }
  94. if (!FusionpSkipBigPathRoot(&arg1[0], &i))
  95. {
  96. ::ReportFailure("FusionpSkipBigPathRoot\n");
  97. goto Exit;
  98. }
  99. p = &arg1[i];
  100. //printf("%ls\n", &arg1[0]);
  101. while (*p != 0)
  102. {
  103. p += wcscspn(p, L"\\/");
  104. *p = 0;
  105. if (!CreateDirectoryW(&arg1[0], NULL))
  106. {
  107. if (::FusionpGetLastWin32Error() != ERROR_ALREADY_EXISTS)
  108. {
  109. ::ReportFailure("CreateDirectoryW\n");
  110. goto Exit;
  111. }
  112. ULONG FileAttributes;
  113. FileAttributes = GetFileAttributesW(&arg1[0]);
  114. if (FileAttributes != 0xffffff && (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
  115. {
  116. ::FusionpSetLastWin32Error(ERROR_ALREADY_EXISTS);
  117. ::ReportFailure("FileInsteadOfDirectoryAlreadyExists\n");
  118. goto Exit;
  119. }
  120. }
  121. printf("%ls\n", &arg1[0]);
  122. *p = '\\';
  123. p += wcsspn(p, L"\\/");
  124. }
  125. //Success:
  126. iReturnStatus = EXIT_SUCCESS;
  127. Exit:
  128. return iReturnStatus;
  129. }