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.

171 lines
3.2 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // CAB file manipulation for extracting dump files
  4. // from dump CABs.
  5. //
  6. // Copyright (C) Microsoft Corporation, 2001.
  7. //
  8. //----------------------------------------------------------------------------
  9. #include "pch.hpp"
  10. #pragma hdrstop
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <sys\stat.h>
  14. #include <share.h>
  15. #include <fdi.h>
  16. #include "cmnutil.hpp"
  17. #define FDI_HR(Code) MAKE_HRESULT(SEVERITY_ERROR, 0xfd1, ((Code) & 0xffff))
  18. struct FDI_CB_STATE
  19. {
  20. PSTR DmpFile;
  21. PSTR DstDir;
  22. ULONG FileFlags;
  23. INT_PTR DmpFh;
  24. };
  25. PSTR
  26. FdiPathTail(PSTR Path)
  27. {
  28. PSTR Tail = strrchr(Path, '\\');
  29. if (Tail == NULL)
  30. {
  31. Tail = strrchr(Path, '/');
  32. if (Tail == NULL)
  33. {
  34. Tail = strrchr(Path, ':');
  35. }
  36. }
  37. return Tail ? Tail + 1 : Path;
  38. }
  39. FNALLOC(FdiAlloc)
  40. {
  41. return malloc(cb);
  42. }
  43. FNFREE(FdiFree)
  44. {
  45. free(pv);
  46. }
  47. FNOPEN(FdiOpen)
  48. {
  49. return _open(pszFile, oflag, pmode);
  50. }
  51. FNREAD(FdiRead)
  52. {
  53. return _read((int)hf, pv, cb);
  54. }
  55. FNWRITE(FdiWrite)
  56. {
  57. return _write((int)hf, pv, cb);
  58. }
  59. FNCLOSE(FdiClose)
  60. {
  61. return _close((int)hf);
  62. }
  63. FNSEEK(FdiSeek)
  64. {
  65. return _lseek((int)hf, dist, seektype);
  66. }
  67. FNFDINOTIFY(FdiNotify)
  68. {
  69. FDI_CB_STATE* CbState = (FDI_CB_STATE*)pfdin->pv;
  70. PSTR Scan;
  71. switch(fdint)
  72. {
  73. case fdintCOPY_FILE:
  74. if (CbState->DmpFh >= 0)
  75. {
  76. return 0;
  77. }
  78. Scan = strrchr(pfdin->psz1, '.');
  79. if (Scan == NULL ||
  80. (_stricmp(Scan, ".dmp") != 0 &&
  81. _stricmp(Scan, ".mdmp") != 0))
  82. {
  83. return 0;
  84. }
  85. Scan = FdiPathTail(pfdin->psz1);
  86. if (*CbState->DstDir)
  87. {
  88. sprintf(CbState->DmpFile, "%s\\%s", CbState->DstDir, Scan);
  89. }
  90. else
  91. {
  92. strcpy(CbState->DmpFile, Scan);
  93. }
  94. CbState->DmpFh = FdiOpen(CbState->DmpFile,
  95. _O_BINARY | _O_WRONLY | CbState->FileFlags,
  96. _S_IREAD | _S_IWRITE);
  97. return CbState->DmpFh;
  98. case fdintCLOSE_FILE_INFO:
  99. // Leave the file open.
  100. return TRUE;
  101. }
  102. return 0;
  103. }
  104. HRESULT
  105. ExpandDumpCab(PCSTR CabFile, ULONG FileFlags,
  106. PSTR DmpFile, INT_PTR* DmpFh)
  107. {
  108. FDI_CB_STATE CbState;
  109. HFDI Context;
  110. ERF Err;
  111. BOOL Status;
  112. PSTR Env;
  113. Env = getenv("TMP");
  114. if (Env == NULL)
  115. {
  116. Env = getenv("TEMP");
  117. if (Env == NULL)
  118. {
  119. Env = "";
  120. }
  121. }
  122. CbState.DmpFile = DmpFile;
  123. CbState.DstDir = Env;
  124. CbState.FileFlags = FileFlags;
  125. CbState.DmpFh = -1;
  126. Context = FDICreate(FdiAlloc, FdiFree,
  127. FdiOpen, FdiRead, FdiWrite, FdiClose, FdiSeek,
  128. cpuUNKNOWN, &Err);
  129. if (Context == NULL)
  130. {
  131. return FDI_HR(Err.erfOper);
  132. }
  133. Status = FDICopy(Context, "", (PSTR)CabFile, 0,
  134. FdiNotify, NULL, &CbState);
  135. FDIDestroy(Context);
  136. if (!Status)
  137. {
  138. return FDI_HR(Err.erfOper);
  139. }
  140. *DmpFh = CbState.DmpFh;
  141. return (CbState.DmpFh >= 0) ? S_OK : E_NOINTERFACE;
  142. }