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.

205 lines
4.9 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. cf.c
  5. Abstract:
  6. This module implements a utlity that copies files using the
  7. Single Instance Store file system filter functionality.
  8. Author:
  9. Scott Cutshall [scottc] 8-July-1997
  10. Revision History:
  11. --*/
  12. #include "cf.h"
  13. //
  14. // We can have: cf SrcPath DstPath {-o NtFileNameOfFileOnWhichToMakeTheCall}
  15. //
  16. #define BUFF_SIZE 2048
  17. void __cdecl
  18. main(
  19. int argc,
  20. char **argv
  21. )
  22. {
  23. NTSTATUS Status;
  24. IO_STATUS_BLOCK IoStatusBlock;
  25. HANDLE volHandle;
  26. UNICODE_STRING srcFileName, dstFileName;
  27. UNICODE_STRING srcDosFileName, dstDosFileName;
  28. UNICODE_STRING callOnFileName;
  29. PSI_COPYFILE copyFile;
  30. ULONG NameBuffer[BUFF_SIZE];
  31. OBJECT_ATTRIBUTES objectAttributes;
  32. IO_STATUS_BLOCK ioStatusBlock;
  33. int i;
  34. copyFile = (PSI_COPYFILE) NameBuffer;
  35. if (argc != 3 && argc != 5)
  36. Usage();
  37. if (argc == 5) {
  38. if (strcmp(argv[3],"-o")) {
  39. Usage();
  40. }
  41. }
  42. //
  43. // Convert the ansii names to unicode and place in the copyFile buffer.
  44. //
  45. RtlCreateUnicodeStringFromAsciiz( &srcDosFileName, argv[1] );
  46. RtlCreateUnicodeStringFromAsciiz( &dstDosFileName, argv[2] );
  47. RtlDosPathNameToNtPathName_U(
  48. srcDosFileName.Buffer,
  49. &srcFileName,
  50. NULL,
  51. NULL );
  52. RtlDosPathNameToNtPathName_U(
  53. dstDosFileName.Buffer,
  54. &dstFileName,
  55. NULL,
  56. NULL );
  57. copyFile->SourceFileNameLength = srcFileName.Length + sizeof(WCHAR);
  58. copyFile->DestinationFileNameLength = dstFileName.Length + sizeof(WCHAR);
  59. copyFile->Flags = COPYFILE_SIS_REPLACE;
  60. RtlCopyMemory(
  61. &copyFile->FileNameBuffer[0],
  62. srcFileName.Buffer,
  63. copyFile->SourceFileNameLength);
  64. RtlCopyMemory(
  65. &copyFile->FileNameBuffer[copyFile->SourceFileNameLength / sizeof(WCHAR)],
  66. dstFileName.Buffer,
  67. copyFile->DestinationFileNameLength);
  68. #define copyFileSize (FIELD_OFFSET(SI_COPYFILE, FileNameBuffer) + \
  69. copyFile->SourceFileNameLength + \
  70. copyFile->DestinationFileNameLength)
  71. if (argc == 3) {
  72. //
  73. // Get a handle to the source file's containing directory to pass into
  74. // FSCTL_SIS_COPYFILE,
  75. //
  76. for (i = srcFileName.Length / sizeof(WCHAR) - 1;
  77. i >= 0 && srcFileName.Buffer[i] != '\\';
  78. --i)
  79. continue;
  80. srcFileName.Length = (USHORT)(i * sizeof(WCHAR));
  81. InitializeObjectAttributes(
  82. &objectAttributes,
  83. &srcFileName,
  84. OBJ_CASE_INSENSITIVE,
  85. NULL,
  86. NULL);
  87. } else {
  88. //
  89. // Get a handle to the NT file specified in argv[4] to send down the call on.
  90. //
  91. unsigned i;
  92. callOnFileName.MaximumLength = callOnFileName.Length = sizeof(WCHAR) * strlen(argv[4]);
  93. callOnFileName.Buffer = (PWCHAR)malloc(callOnFileName.MaximumLength);
  94. for (i = 0; i < strlen(argv[4]); i++) {
  95. callOnFileName.Buffer[i] = argv[4][i];
  96. }
  97. InitializeObjectAttributes(
  98. &objectAttributes,
  99. &callOnFileName,
  100. OBJ_CASE_INSENSITIVE,
  101. NULL,
  102. NULL);
  103. }
  104. Status = NtCreateFile(
  105. &volHandle,
  106. GENERIC_READ,
  107. &objectAttributes,
  108. &ioStatusBlock,
  109. NULL,
  110. 0,
  111. FILE_SHARE_READ|FILE_SHARE_WRITE,
  112. OPEN_EXISTING,
  113. 0,
  114. NULL,
  115. 0);
  116. if (!NT_SUCCESS(Status)) {
  117. if (5 == argc) {
  118. fprintf(stderr, "Unable to open file, %.*ls (%x)\n",
  119. callOnFileName.Length / sizeof(WCHAR), callOnFileName.Buffer, Status);
  120. } else {
  121. fprintf(stderr, "Unable to open directory, %.*ls (%x)\n",
  122. srcFileName.Length / sizeof(WCHAR), srcFileName.Buffer, Status);
  123. }
  124. exit(1);
  125. }
  126. //
  127. // Invoke the SIS CopyFile FsCtrl.
  128. //
  129. Status = NtFsControlFile(
  130. volHandle,
  131. NULL,
  132. NULL,
  133. NULL,
  134. &IoStatusBlock,
  135. FSCTL_SIS_COPYFILE,
  136. copyFile, // Input buffer
  137. copyFileSize, // Input buffer length
  138. NULL, // Output buffer
  139. 0 ); // Output buffer length
  140. if (NT_SUCCESS( Status )) {
  141. fprintf( stderr, "NtFsControlFile CopyFile succeeded\n" );
  142. } else {
  143. fprintf( stderr, "NtFsControlFile CopyFile failed %x\n", Status );
  144. }
  145. exit (0);
  146. } // main
  147. void
  148. Usage( void )
  149. {
  150. fprintf( stderr, "\n" );
  151. fprintf( stderr, "Usage: cf Path1 Path2 {-o NtFileNameOfFileOnWhichToMakeTheCall}\n" );
  152. fprintf( stderr, " cf copies Path1 to Path2 using SIS links.\n" );
  153. fprintf( stderr, " if -o is specified, opens that file to send down the call on,\n");
  154. fprintf( stderr, " rather than using the directory containing the source file.\n");
  155. exit(1);
  156. } // Usage