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.

222 lines
8.5 KiB

  1. #include "CommandLine.h"
  2. #include <malloc.h>
  3. BOOL WINAPI MakeSureDirectoryPathExistsW(LPCWSTR DirPath);
  4. DWORD WINAPI CheckCommandLineOptions(INT ArgC, LPWSTR* ArgVW) {
  5. DWORD dwReturnFlags = 0;
  6. INT i;
  7. WCHAR* cp;
  8. WCHAR wszInstallPath[MAX_PATH+1];
  9. for (i = 1; i < ArgC && wcschr(L"/-",ArgVW[i][0]) != NULL; ++i) {
  10. for (cp = &ArgVW[i][1]; *cp != L'\0'; ++cp) {
  11. switch (towupper(*cp)) {
  12. case L'U': {
  13. HKEY hKey;
  14. LONG lStatus = 0;
  15. LONG lCreatedOrOpened = 0;
  16. SET_FLAG(dwReturnFlags, FLAG_UNATTENDED_INSTALL);
  17. // next param isn't a flag (or NULL), so it *must* be the path to install to
  18. if ( (i+1 < ArgC) && wcschr(L"/-",ArgVW[i+1][0]) == NULL ) {
  19. i++; // account for the parameter removed
  20. SET_FLAG(dwReturnFlags, FLAG_UNATTENDED_PATH_PROVIDED);
  21. StringCchCopyW(wszInstallPath, MAX_PATH+1, ArgVW[i]);
  22. // make sure path ends in '\'
  23. if (wszInstallPath[wcslen(wszInstallPath)]!=L'\\')
  24. StringCchCatW(wszInstallPath,MAX_PATH+1,L"\\");
  25. // make sure the directory exists!
  26. if (! MakeSureDirectoryPathExistsW(wszInstallPath) ) {
  27. SET_FLAG(dwReturnFlags, FLAG_FATAL_ERROR);
  28. } else {
  29. // Either create the regkey (if it doesn't exist) or open it (if it
  30. // does exist). lCreatedOrOpened can be tested against
  31. // REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY to determine which
  32. // occurred.
  33. lStatus = RegCreateKeyExW(SYMBOLS_REGKEY_ROOT,
  34. SYMBOLS_REGKEY_PATH,
  35. 0,
  36. NULL,
  37. REG_OPTION_NON_VOLATILE,
  38. KEY_ALL_ACCESS,
  39. NULL,
  40. &hKey,
  41. &lCreatedOrOpened);
  42. if (lStatus != ERROR_SUCCESS) {
  43. SET_FLAG(dwReturnFlags, FLAG_FATAL_ERROR);
  44. } else {
  45. // Write the value of the path to SYMBOLS_REGKEY
  46. lStatus = RegSetValueExW( hKey, SYMBOLS_REGKEY, 0, REG_SZ, (BYTE*)wszInstallPath, ((wcslen(wszInstallPath) + 1) * sizeof(WCHAR)));
  47. if (lStatus != ERROR_SUCCESS) {
  48. SET_FLAG(dwReturnFlags, FLAG_FATAL_ERROR);
  49. }
  50. // close the regkey
  51. lStatus = RegCloseKey( hKey );
  52. if (lStatus != ERROR_SUCCESS) {
  53. SET_FLAG(dwReturnFlags, FLAG_ERROR);
  54. }
  55. }
  56. } // else ...
  57. // couldn't set the path requests, so use what's
  58. // already in the registry.
  59. } // else ...
  60. // no path provided, so don't set anything- setupapi will
  61. // nicely use the existing key or default to the value
  62. // specified in the INF
  63. // StringCchCopyW(wszInstallPath, MAX_PATH+1, DEFAULT_INSTALL_PATH);
  64. }
  65. break;
  66. case L'Q':
  67. SET_FLAG(dwReturnFlags, FLAG_TOTALLY_QUIET);
  68. break;
  69. case L'?': // explicit fall through
  70. case L'H': // explicit fall through
  71. default:
  72. SET_FLAG(dwReturnFlags, FLAG_USAGE);
  73. break;
  74. }
  75. }
  76. }
  77. if ( IS_FLAG_SET(dwReturnFlags, FLAG_USAGE) ) {
  78. WCHAR UsageBuffer[1024];
  79. StringCchPrintfW(UsageBuffer,
  80. sizeof(UsageBuffer)/sizeof(WCHAR),
  81. L"Usage: %s [ /u [<path>] [/q] ]\n\n"
  82. L"/u [<path>] \n"
  83. L" Unattended install. If <path> is specified install\n"
  84. L" symbols to <path>. If no path is specified, symbols\n"
  85. L" are installed to the default location.\n"
  86. L" NOTE: USING UNATTENDED INSTALL MEANS YOU\n"
  87. L" HAVE READ AND AGREED TO THE END USER LICENSE\n"
  88. L" AGREEMENT FOR THIS PRODUCT.\n"
  89. L"/q\n"
  90. L" Valid only when using unattended install. Prevents\n"
  91. L" error messages from being display if unattended\n"
  92. L" install fails.\n"
  93. L"/?\n"
  94. L" Show this dialog box.\n\n"
  95. L"If no options are specified, the interactive installation\n"
  96. L" is started.",
  97. ArgVW[0]);
  98. MessageBoxW( NULL,
  99. UsageBuffer,
  100. L"Microsoft Windows Symbols",
  101. 0 );
  102. }
  103. return(dwReturnFlags);
  104. }
  105. // Modified from MakeSureDirectoryPathExists from dbghelp.h
  106. // The same caveats apply. (see MSDN)
  107. BOOL WINAPI MakeSureDirectoryPathExistsW(LPCWSTR DirPath) {
  108. LPWSTR p, DirCopy;
  109. DWORD dw;
  110. // Make a copy of the string for editing.
  111. __try {
  112. DirCopy = (LPWSTR)malloc((wcslen(DirPath) + 1) * sizeof(WCHAR));
  113. if (!DirCopy) {
  114. return FALSE;
  115. }
  116. StringCchCopyW(DirCopy, wcslen(DirPath)+1, DirPath);
  117. p = DirCopy;
  118. // If the second character in the path is "\", then this is a UNC
  119. // path, and we should skip forward until we reach the 2nd \ in the path.
  120. if ((*p == L'\\') && (*(p+1) == L'\\')) {
  121. p++; // Skip over the first \ in the name.
  122. p++; // Skip over the second \ in the name.
  123. // Skip until we hit the first "\" (\\Server\).
  124. while (*p && *p != L'\\') {
  125. p = CharNextW(p);
  126. }
  127. // Advance over it.
  128. if (*p) {
  129. p++;
  130. }
  131. // Skip until we hit the second "\" (\\Server\Share\).
  132. while (*p && *p != L'\\') {
  133. p = CharNextW(p);
  134. }
  135. // Advance over it also.
  136. if (*p) {
  137. p++;
  138. }
  139. } else
  140. // Not a UNC. See if it's <drive>:
  141. if (*(p+1) == L':' ) {
  142. p++;
  143. p++;
  144. // If it exists, skip over the root specifier
  145. if (*p && (*p == L'\\')) {
  146. p++;
  147. }
  148. }
  149. while( *p ) {
  150. if ( *p == '\\' ) {
  151. *p = '\0';
  152. dw = GetFileAttributesW(DirCopy);
  153. // Nothing exists with this name. Try to make the directory name and error if unable to.
  154. if ( dw == 0xffffffff ) {
  155. if ( !CreateDirectoryW(DirCopy,NULL) ) {
  156. if( GetLastError() != ERROR_ALREADY_EXISTS ) {
  157. free(DirCopy);
  158. return FALSE;
  159. }
  160. }
  161. } else {
  162. if ( (dw & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) {
  163. // Something exists with this name, but it's not a directory... Error
  164. free(DirCopy);
  165. return FALSE;
  166. }
  167. }
  168. *p = L'\\';
  169. }
  170. p = CharNextW(p);
  171. }
  172. } __except (EXCEPTION_EXECUTE_HANDLER) {
  173. SetLastError( GetExceptionCode() );
  174. free(DirCopy);
  175. return(FALSE);
  176. }
  177. free(DirCopy);
  178. return TRUE;
  179. }