Source code of Windows XP (NT5)
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.

206 lines
4.5 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. openclose.c
  5. Abstract:
  6. This module contains the code to open and
  7. close a cab file.
  8. Author:
  9. Wesley Witt (wesw) 29-Sept-1998
  10. Revision History:
  11. --*/
  12. #include <ntcabp.h>
  13. #pragma hdrstop
  14. BOOL
  15. NtCabOpenCabFile(
  16. IN PCAB_INSTANCE_DATA CabInst,
  17. IN PCWSTR CabFileName
  18. )
  19. {
  20. BOOL rVal;
  21. HANDLE hCab;
  22. DWORD Bytes;
  23. DWORD FileSize;
  24. PULONG Lengths;
  25. DWORD i;
  26. PLIST_ENTRY Next;
  27. PCAB_DIR_ENTRY CabDir;
  28. CAB_HEADER CabHeader;
  29. CabInst->hCab = CreateFile(
  30. CabFileName,
  31. GENERIC_WRITE | GENERIC_READ,
  32. 0,
  33. NULL,
  34. OPEN_EXISTING,
  35. FILE_ATTRIBUTE_NORMAL,
  36. NULL
  37. );
  38. if (CabInst->hCab == INVALID_HANDLE_VALUE) {
  39. return FALSE;
  40. }
  41. FileSize = GetFileSize( CabInst->hCab, NULL );
  42. rVal = ReadFile(
  43. CabInst->hCab,
  44. &CabHeader,
  45. sizeof(CAB_HEADER),
  46. &Bytes,
  47. NULL
  48. );
  49. if (!rVal) {
  50. CloseHandle( CabInst->hCab );
  51. return FALSE;
  52. }
  53. if ((CabHeader.Signature != NTCAB_SIGNATURE) ||
  54. (CabHeader.Version != NTCAB_VERSION))
  55. {
  56. return FALSE;
  57. }
  58. CabInst->CabDirOffset = CabHeader.DirOffset;
  59. if (SetFilePointer( CabInst->hCab, CabInst->CabDirOffset, NULL, FILE_BEGIN ) == 0xffffffff) {
  60. CloseHandle( CabInst->hCab );
  61. return FALSE;
  62. }
  63. InitializeListHead( &CabInst->CabDir );
  64. rVal = ReadFile(
  65. CabInst->hCab,
  66. &CabInst->CabNum,
  67. sizeof(ULONG),
  68. &Bytes,
  69. NULL
  70. );
  71. Lengths = (PULONG) malloc( CabInst->CabNum * sizeof(ULONG) );
  72. if (Lengths == NULL) {
  73. CloseHandle( CabInst->hCab );
  74. return FALSE;
  75. }
  76. rVal = ReadFile(
  77. CabInst->hCab,
  78. Lengths,
  79. CabInst->CabNum * sizeof(ULONG),
  80. &Bytes,
  81. NULL
  82. );
  83. for (i=0; i<CabInst->CabNum; i++) {
  84. Bytes = sizeof(CAB_DIR_ENTRY) + (sizeof(ULONG)*Lengths[i]);
  85. CabDir = (PCAB_DIR_ENTRY) malloc( Bytes );
  86. if (CabDir == NULL) {
  87. CloseHandle( CabInst->hCab );
  88. return FALSE;
  89. }
  90. rVal = ReadFile(
  91. CabInst->hCab,
  92. CabDir,
  93. Lengths[i],
  94. &Bytes,
  95. NULL
  96. );
  97. ZeroMemory( &CabDir->Next, sizeof(LIST_ENTRY) );
  98. InsertTailList( &CabInst->CabDir, &CabDir->Next );
  99. }
  100. CabInst->CabFileName = _wcsdup( CabFileName );
  101. return TRUE;
  102. }
  103. BOOL
  104. NtCabClose(
  105. IN PCAB_INSTANCE_DATA CabInst
  106. )
  107. {
  108. NTSTATUS Status;
  109. DWORD Bytes;
  110. DWORD DirOffset;
  111. PULONG Lengths;
  112. DWORD i;
  113. PLIST_ENTRY Next;
  114. PCAB_DIR_ENTRY CabDir;
  115. CAB_HEADER CabHeader;
  116. if (CabInst->NewCabFile) {
  117. if (IsListEmpty(&CabInst->CabDir)) {
  118. return FALSE;
  119. }
  120. DirOffset = SetFilePointer( CabInst->hCab, 0, NULL, FILE_END );
  121. Lengths = (PULONG) malloc( CabInst->CabNum * sizeof(ULONG) );
  122. if (Lengths == NULL) {
  123. CloseHandle( CabInst->hCab );
  124. return FALSE;
  125. }
  126. i = 0;
  127. Next = CabInst->CabDir.Flink;
  128. while ((ULONG_PTR)Next != (ULONG_PTR)&CabInst->CabDir) {
  129. CabDir = CONTAINING_RECORD( Next, CAB_DIR_ENTRY, Next );
  130. Next = CabDir->Next.Flink;
  131. Lengths[i] = (CabDir->Segments * sizeof(ULONG)) + sizeof(CAB_DIR_ENTRY);
  132. i += 1;
  133. }
  134. Status = WriteFile(
  135. CabInst->hCab,
  136. &CabInst->CabNum,
  137. sizeof(ULONG),
  138. &Bytes,
  139. NULL
  140. );
  141. Status = WriteFile(
  142. CabInst->hCab,
  143. Lengths,
  144. CabInst->CabNum * sizeof(ULONG),
  145. &Bytes,
  146. NULL
  147. );
  148. i = 0;
  149. Next = CabInst->CabDir.Flink;
  150. while ((ULONG_PTR)Next != (ULONG_PTR)&CabInst->CabDir) {
  151. CabDir = CONTAINING_RECORD( Next, CAB_DIR_ENTRY, Next );
  152. Next = CabDir->Next.Flink;
  153. Status = WriteFile(
  154. CabInst->hCab,
  155. CabDir,
  156. Lengths[i++],
  157. &Bytes,
  158. NULL
  159. );
  160. }
  161. SetFilePointer( CabInst->hCab, 0, NULL, FILE_BEGIN );
  162. CabHeader.Signature = NTCAB_SIGNATURE;
  163. CabHeader.Version = NTCAB_VERSION;
  164. CabHeader.DirOffset = DirOffset;
  165. Status = WriteFile(
  166. CabInst->hCab,
  167. &CabHeader,
  168. sizeof(CAB_HEADER),
  169. &Bytes,
  170. NULL
  171. );
  172. }
  173. CloseHandle( CabInst->hCab );
  174. return TRUE;
  175. }