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.

309 lines
6.1 KiB

  1. /*
  2. * util.cpp
  3. */
  4. #include <pch.h>
  5. char *CompressedFileName(char *name)
  6. {
  7. char c;
  8. DWORD len;
  9. static char sz[MAX_PATH + 1];
  10. CopyStrArray(sz, name);
  11. len = strlen(sz) - 1;
  12. sz[len] = '_';
  13. return sz;
  14. }
  15. void
  16. EnsureTrailingChar(
  17. char *sz,
  18. char c
  19. )
  20. {
  21. int i;
  22. assert(sz);
  23. i = strlen(sz);
  24. if (!i)
  25. return;
  26. if (sz[i - 1] == c)
  27. return;
  28. sz[i] = c;
  29. sz[i + 1] = '\0';
  30. }
  31. void EnsureTrailingBackslash(char *sz)
  32. {
  33. return EnsureTrailingChar(sz, '\\');
  34. }
  35. void EnsureTrailingSlash(char *sz)
  36. {
  37. return EnsureTrailingChar(sz, '/');
  38. }
  39. void EnsureTrailingCR(char *sz)
  40. {
  41. return EnsureTrailingChar(sz, '\n');
  42. }
  43. void
  44. pathcpy(
  45. LPSTR trg,
  46. LPCSTR path,
  47. LPCSTR node,
  48. DWORD size
  49. )
  50. {
  51. assert (trg && path && node);
  52. CopyString(trg, path, size);
  53. EnsureTrailingBackslash(trg);
  54. CatString(trg, node, size);
  55. }
  56. void
  57. pathcat(
  58. LPSTR path,
  59. LPCSTR node,
  60. DWORD size
  61. )
  62. {
  63. assert(path && node);
  64. EnsureTrailingBackslash(path);
  65. CatString(path, node, size);
  66. }
  67. void ConvertBackslashes(LPSTR sz)
  68. {
  69. for (; *sz; sz++) {
  70. if (*sz == '\\')
  71. *sz = '/';
  72. }
  73. }
  74. DWORD FileStatus(LPCSTR file)
  75. {
  76. DWORD rc;
  77. if (GetFileAttributes(file) != 0xFFFFFFFF)
  78. return NO_ERROR;
  79. rc = GetLastError();
  80. if (rc)
  81. rc = ERROR_FILE_NOT_FOUND;
  82. return rc;
  83. }
  84. char *FormatStatus(HRESULT status)
  85. {
  86. static char buf[2048];
  87. DWORD len = 0;
  88. PVOID hm;
  89. DWORD flags;
  90. if (status == 0x50)
  91. assert(0);
  92. // By default, get error text from the system error list.
  93. flags = FORMAT_MESSAGE_FROM_SYSTEM;
  94. // If this is an NT code and ntdll is around,
  95. // allow messages to be retrieved from it also.
  96. if ((DWORD)status & FACILITY_NT_BIT) {
  97. hm = GetModuleHandle("ntdll");
  98. if (hm) {
  99. flags |= FORMAT_MESSAGE_FROM_HMODULE;
  100. status &= ~FACILITY_NT_BIT;
  101. }
  102. }
  103. if (!len)
  104. len = FormatMessage(flags | FORMAT_MESSAGE_IGNORE_INSERTS,
  105. hm,
  106. status,
  107. 0,
  108. buf,
  109. 2048,
  110. NULL);
  111. if (len > 0) {
  112. while (len > 0 && isspace(buf[len - 1]))
  113. buf[--len] = 0;
  114. }
  115. if (len < 1)
  116. wsprintf(buf, "error 0x%x", status);
  117. if (*(buf + strlen(buf) - 1) == '\n')
  118. *(buf + strlen(buf) - 1) = 0;
  119. return buf;
  120. }
  121. /*
  122. * stolen from dbghelp.dll to avoid circular dll loads
  123. */
  124. BOOL
  125. EnsurePathExists(
  126. LPCSTR DirPath,
  127. LPSTR ExistingPath,
  128. DWORD ExistingPathSize
  129. )
  130. {
  131. CHAR dir[_MAX_PATH + 1];
  132. LPSTR p;
  133. DWORD dw;
  134. __try {
  135. if (ExistingPath)
  136. *ExistingPath = 0;
  137. // Make a copy of the string for editing.
  138. if (!CopyString(dir, DirPath, _MAX_PATH))
  139. return false;
  140. p = dir;
  141. // If the second character in the path is "\", then this is a UNC
  142. // path, and we should skip forward until we reach the 2nd \ in the path.
  143. if ((*p == '\\') && (*(p+1) == '\\')) {
  144. p++; // Skip over the first \ in the name.
  145. p++; // Skip over the second \ in the name.
  146. // Skip until we hit the first "\" (\\Server\).
  147. while (*p && *p != '\\') {
  148. p++;
  149. }
  150. // Advance over it.
  151. if (*p) {
  152. p++;
  153. }
  154. // Skip until we hit the second "\" (\\Server\Share\).
  155. while (*p && *p != '\\') {
  156. p++;
  157. }
  158. // Advance over it also.
  159. if (*p) {
  160. p++;
  161. }
  162. } else
  163. // Not a UNC. See if it's <drive>:
  164. if (*p && *(p+1) == ':' ) {
  165. p++;
  166. p++;
  167. // If it exists, skip over the root specifier
  168. if (*p && (*p == '\\')) {
  169. p++;
  170. }
  171. }
  172. while( *p ) {
  173. if ( *p == '\\' ) {
  174. *p = 0;
  175. dw = GetFileAttributes(dir);
  176. // Nothing exists with this name. Try to make the directory name and error if unable to.
  177. if ( dw == 0xffffffff ) {
  178. if ( !CreateDirectory(dir,NULL) ) {
  179. if( GetLastError() != ERROR_ALREADY_EXISTS ) {
  180. return false;
  181. }
  182. }
  183. } else {
  184. if ( (dw & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) {
  185. // Something exists with this name, but it's not a directory... Error
  186. return false;
  187. } else {
  188. if (ExistingPath)
  189. CopyString(ExistingPath, dir, ExistingPathSize);
  190. }
  191. }
  192. *p = '\\';
  193. }
  194. p++;
  195. }
  196. SetLastError(NO_ERROR);
  197. } __except (EXCEPTION_EXECUTE_HANDLER) {
  198. SetLastError( GetExceptionCode() );
  199. return false;
  200. }
  201. return true;
  202. }
  203. BOOL
  204. UndoPath(
  205. LPCSTR DirPath,
  206. LPCSTR BasePath
  207. )
  208. {
  209. CHAR dir[_MAX_PATH + 1];
  210. LPSTR p;
  211. DWORD dw;
  212. dw = GetLastError();
  213. __try
  214. {
  215. if (!CopyString(dir, DirPath, _MAX_PATH))
  216. return false;
  217. for (p = dir + strlen(dir); p > dir; p--)
  218. {
  219. if (*p == '\\')
  220. {
  221. *p = 0;
  222. if (*BasePath && !_stricmp(dir, BasePath))
  223. break;
  224. if (!RemoveDirectory(dir))
  225. break;
  226. }
  227. }
  228. }
  229. __except (EXCEPTION_EXECUTE_HANDLER)
  230. {
  231. SetLastError( GetExceptionCode() );
  232. return false;
  233. }
  234. SetLastError(dw);
  235. return true;
  236. }