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.

277 lines
5.6 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. dndelnod.c
  5. Abstract:
  6. Delnode routine for winnt.
  7. Author:
  8. Ted Miller (tedm) August 1992
  9. --*/
  10. #include "winnt.h"
  11. #include <string.h>
  12. #include <dos.h>
  13. #include <io.h>
  14. #include <direct.h>
  15. #define MAX_PATH 256
  16. //
  17. // This number here is probably a lot larger than necessary; this is
  18. // the static number of find-data blobs below. Will we ever have a
  19. // path depth larger than 32? If so, we'll heap allocate.
  20. //
  21. #define FIND_DATA_COUNT ( 32 )
  22. //
  23. // Put this out here to cut stack consumption.
  24. //
  25. CHAR Pattern[MAX_PATH+1];
  26. //
  27. // A static array of these should clean up all stack corruption/overflow
  28. // problems.
  29. //
  30. struct find_t FindDataList[FIND_DATA_COUNT];
  31. unsigned FindDataIndex;
  32. VOID
  33. DnpDelnodeWorker(
  34. VOID
  35. )
  36. /*++
  37. Routine Description:
  38. Delete all files in a directory, and make recursive calls for any
  39. directories found in the directory.
  40. Arguments:
  41. None. The Pattern variable should contain the name of the directory
  42. whose files are to be deleted.
  43. Return Value:
  44. None.
  45. --*/
  46. {
  47. PCHAR PatternEnd;
  48. //
  49. // Pointer into the global pseudostack of find_t structures above.
  50. //
  51. struct find_t *pFindData;
  52. //
  53. // Did we allocate the find data off the heap or from the list above?
  54. //
  55. BOOLEAN HeapAllocatedFindData = FALSE;
  56. //
  57. // Delete each file in the directory, then remove the directory itself.
  58. // If any directories are encountered along the way recurse to delete
  59. // them as they are encountered.
  60. //
  61. PatternEnd = Pattern+strlen(Pattern);
  62. strcat(Pattern,"\\*.*");
  63. //
  64. // Ensure we've got a find data object for this run.
  65. //
  66. if ( FindDataIndex < FIND_DATA_COUNT ) {
  67. //
  68. // Point the current find data object into the find data list
  69. // at the next available entry.
  70. //
  71. pFindData = FindDataList + FindDataIndex++;
  72. HeapAllocatedFindData = FALSE;
  73. } else {
  74. //
  75. // Otherwise, try to allocate from the heap. If this fails, we're
  76. // up a creek. (Keep track of whether we did this from the
  77. // heap or not, as well.)
  78. //
  79. pFindData = MALLOC(sizeof(struct find_t), TRUE);
  80. if ( pFindData != NULL ) {
  81. HeapAllocatedFindData = TRUE;
  82. }
  83. }
  84. if(!_dos_findfirst(Pattern,_A_HIDDEN|_A_SYSTEM|_A_SUBDIR,pFindData)) {
  85. do {
  86. //
  87. // Form the full name of the file we just found.
  88. //
  89. strcpy(PatternEnd+1,pFindData->name);
  90. //
  91. // Remove read-only atttribute if it's there.
  92. //
  93. if(pFindData->attrib & _A_RDONLY) {
  94. _dos_setfileattr(Pattern,_A_NORMAL);
  95. }
  96. if(pFindData->attrib & _A_SUBDIR) {
  97. //
  98. // The current match is a directory. Recurse into it unless
  99. // it's . or ...
  100. //
  101. if(strcmp(pFindData->name,".") && strcmp(pFindData->name,"..")) {
  102. DnpDelnodeWorker();
  103. }
  104. } else {
  105. //
  106. // The current match is not a directory -- so delete it.
  107. //
  108. DnWriteStatusText(DntRemovingFile,Pattern);
  109. remove(Pattern);
  110. }
  111. *(PatternEnd+1) = 0;
  112. } while(!_dos_findnext(pFindData));
  113. }
  114. //
  115. // Remove the directory we just emptied out.
  116. //
  117. *PatternEnd = 0;
  118. DnWriteStatusText(DntRemovingFile,Pattern);
  119. _dos_setfileattr(Pattern,_A_NORMAL);
  120. if(!_dos_findfirst(Pattern,_A_HIDDEN|_A_SYSTEM|_A_SUBDIR,pFindData)
  121. && (pFindData->attrib & _A_SUBDIR))
  122. {
  123. rmdir(Pattern);
  124. } else {
  125. remove(Pattern);
  126. }
  127. if ( HeapAllocatedFindData && ( pFindData != NULL ) ) {
  128. FREE( pFindData );
  129. } else {
  130. //
  131. // Pop an entry off the find data array
  132. //
  133. FindDataIndex--;
  134. }
  135. }
  136. VOID
  137. DnDelnode(
  138. IN PCHAR Directory
  139. )
  140. /*++
  141. Routine Description:
  142. Delete all files in a directory tree rooted at a given path.
  143. Arguments:
  144. Directory - supplies full path to the root of the subdirectory to be
  145. removed. If this is actually a file, the file will be deleted.
  146. Return Value:
  147. None.
  148. --*/
  149. {
  150. DnClearClientArea();
  151. DnDisplayScreen(&DnsWaitCleanup);
  152. strcpy(Pattern,Directory);
  153. FindDataIndex = 0;
  154. DnpDelnodeWorker();
  155. }
  156. VOID
  157. DnRemoveLocalSourceTrees(
  158. VOID
  159. )
  160. /*++
  161. Routine Description:
  162. Scan for local source trees on local hard drives and delnode them.
  163. Arguments:
  164. None.
  165. Return Value:
  166. None.
  167. --*/
  168. {
  169. struct find_t FindData;
  170. CHAR Filename[sizeof(LOCAL_SOURCE_DIRECTORY) + 2];
  171. unsigned Drive;
  172. Filename[1] = ':';
  173. strcpy(Filename+2,LocalSourceDirName);
  174. DnWriteStatusText(DntInspectingComputer);
  175. DnClearClientArea();
  176. for(Filename[0]='A',Drive=1; Filename[0]<='Z'; Filename[0]++,Drive++) {
  177. if(DnIsDriveValid(Drive)
  178. && !DnIsDriveRemote(Drive,NULL)
  179. && !DnIsDriveRemovable(Drive)
  180. && !_dos_findfirst(Filename,_A_HIDDEN|_A_SYSTEM|_A_SUBDIR,&FindData))
  181. {
  182. DnDelnode(Filename);
  183. DnWriteStatusText(DntInspectingComputer);
  184. DnClearClientArea();
  185. }
  186. }
  187. }