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.

231 lines
4.4 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. util.cpp
  5. Abstract:
  6. This code performs file systme and string functions
  7. Author:
  8. patst
  9. --*/
  10. #include "pch.h"
  11. void
  12. EnsureTrailingChar(
  13. char *sz,
  14. char c
  15. )
  16. {
  17. int i;
  18. assert(sz);
  19. i = lstrlen(sz);
  20. if (!i)
  21. return;
  22. if (sz[i - 1] == c)
  23. return;
  24. sz[i] = c;
  25. sz[i + 1] = '\0';
  26. }
  27. void
  28. EnsureTrailingBackslash(
  29. char *sz
  30. )
  31. {
  32. return EnsureTrailingChar(sz, '\\');
  33. }
  34. void
  35. EnsureTrailingSlash(
  36. char *sz
  37. )
  38. {
  39. return EnsureTrailingChar(sz, '/');
  40. }
  41. void
  42. EnsureTrailingCR(
  43. char *sz
  44. )
  45. {
  46. return EnsureTrailingChar(sz, '\n');
  47. }
  48. void
  49. pathcpy(
  50. LPSTR trg,
  51. LPCSTR path,
  52. LPCSTR node,
  53. DWORD trgsize
  54. )
  55. {
  56. assert (trg && path && node);
  57. CopyString(trg, path, trgsize);
  58. EnsureTrailingBackslash(trg);
  59. CatString(trg, node, trgsize);
  60. }
  61. BOOL
  62. EnsurePathExists(
  63. const char *path,
  64. char *existing,
  65. DWORD existingsize,
  66. BOOL fNoFileName
  67. )
  68. {
  69. CHAR dir[_MAX_PATH + 1];
  70. LPSTR p;
  71. DWORD dw;
  72. __try {
  73. if (existing)
  74. *existing = 0;
  75. // Make a copy of the string for editing.
  76. CopyStrArray(dir, path);
  77. if (fNoFileName)
  78. EnsureTrailingBackslash(dir);
  79. p = dir;
  80. // If the second character in the path is "\", then this is a UNC
  81. // path, and we should skip forward until we reach the 2nd \ in the path.
  82. if ((*p == '\\') && (*(p+1) == '\\')) {
  83. p++; // Skip over the first \ in the name.
  84. p++; // Skip over the second \ in the name.
  85. // Skip until we hit the first "\" (\\Server\).
  86. while (*p && *p != '\\') {
  87. p++;
  88. }
  89. // Advance over it.
  90. if (*p) {
  91. p++;
  92. }
  93. // Skip until we hit the second "\" (\\Server\Share\).
  94. while (*p && *p != '\\') {
  95. p++;
  96. }
  97. // Advance over it also.
  98. if (*p) {
  99. p++;
  100. }
  101. } else
  102. // Not a UNC. See if it's <drive>:
  103. if (*(p+1) == ':' ) {
  104. p++;
  105. p++;
  106. // If it exists, skip over the root specifier
  107. if (*p && (*p == '\\')) {
  108. p++;
  109. }
  110. }
  111. while( *p ) {
  112. if ( *p == '\\' ) {
  113. *p = 0;
  114. dw = GetFileAttributes(dir);
  115. // Nothing exists with this name. Try to make the directory name and error if unable to.
  116. if ( dw == 0xffffffff ) {
  117. if ( !CreateDirectory(dir,NULL) ) {
  118. if( GetLastError() != ERROR_ALREADY_EXISTS ) {
  119. return false;
  120. }
  121. }
  122. } else {
  123. if ( (dw & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) {
  124. // Something exists with this name, but it's not a directory... Error
  125. return false;
  126. } else {
  127. if (existing)
  128. CopyString(existing, dir, existingsize);
  129. }
  130. }
  131. *p = '\\';
  132. }
  133. p++;
  134. }
  135. SetLastError(NO_ERROR);
  136. } __except (EXCEPTION_EXECUTE_HANDLER) {
  137. SetLastError( GetExceptionCode() );
  138. return false;
  139. }
  140. return true;
  141. }
  142. BOOL
  143. UndoPath(
  144. char *path,
  145. char *BasePath
  146. )
  147. {
  148. CHAR dir[MAX_PATH + 1];
  149. LPSTR p;
  150. DWORD dw;
  151. dw = GetLastError();
  152. __try
  153. {
  154. CopyStrArray(dir, path);
  155. for (p = dir + strlen(dir); p > dir; p--)
  156. {
  157. if (*p == '\\')
  158. {
  159. *p = 0;
  160. if (*BasePath && !_stricmp(dir, BasePath))
  161. break;
  162. if (!RemoveDirectory(dir))
  163. break;
  164. }
  165. }
  166. }
  167. __except (EXCEPTION_EXECUTE_HANDLER)
  168. {
  169. SetLastError( GetExceptionCode() );
  170. return false;
  171. }
  172. SetLastError(dw);
  173. return true;
  174. }