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.

255 lines
8.7 KiB

  1. #include "inspch.h"
  2. #include "debug.h"
  3. #include "extract.h"
  4. // for ASSERT and FAIL
  5. //
  6. SZTHISFILE
  7. //
  8. //
  9. // THIS FILE IS NOT USED ANYMORE -- EXTRACT FUNCGIONALITY IS NOW IN ADVPACK
  10. // AND IT TALKS TO CABINET.DLL/URLMON.DLL AS APPROPRIATE. THIS WILL BE
  11. // DELFILE-D
  12. //
  13. //
  14. typedef HRESULT (WINAPI *EXTRACT) (PSESSION psess, LPCSTR lpCabName);
  15. VOID FreeFileList(PSESSION psess);
  16. VOID FreeFileNode(PFNAME pfname);
  17. BOOL IsFileInList(LPSTR pszFile, LPSTR pszFileList);
  18. int PrepareFileList(LPSTR pszOutFileList, LPCSTR pszInFileList);
  19. //=--------------------------------------------------------------------------=
  20. // ExtractFiles
  21. //=--------------------------------------------------------------------------=
  22. //
  23. // Parameters:
  24. // LPCSTR pszCabName - [in] full qualified filename to the .CAB file
  25. // LPCSTR pszExpandDir- [in] full qualified path to where to extract the file(s)
  26. // DWORD dwFlags - [in] Flags, currently not used
  27. // LPCSTR pszFileList - [in] colon separated list of files to extract from pszCabName
  28. // or NULL for all files
  29. // LPVOID lpReserved - [in] currently not used
  30. // DWORD dwReserved - [in] currently not used
  31. //
  32. // Return HRESULT:
  33. // E_INVALIDARG - if pszCabName or pszExpandDir == NULL
  34. // E_OUTOFMEMORY - if we could not allocate our memory
  35. // E_FAIL - if no files in pszFileList and pszFileList!=NULL
  36. // if not all files from pszFileList are in the .CAB file
  37. // if Extract return S_FALSE
  38. // any E_ code Extract returns
  39. //
  40. // Note: This function would not extract any file from the pszFileList, if not all
  41. // of them are in the .CAB file. If one or more are not in the .CAB file
  42. // the function does not extract any and returns E_FAIL
  43. //
  44. HRESULT ExtractFiles(LPCSTR pszCabName, LPCSTR pszExpandDir, DWORD dwFlags,
  45. LPCSTR pszFileList, LPVOID lpReserved, DWORD dwReserved)
  46. {
  47. HINSTANCE hinst;
  48. PSESSION psess = NULL;
  49. PFNAME pf = NULL;
  50. PFNAME pfPriv = NULL;
  51. HRESULT hr = E_FAIL; // Return error
  52. LPSTR pszMyFileList = NULL;
  53. EXTRACT fpExtract = NULL;
  54. int iFiles = 0; // number of files in list
  55. // Do checking for valid values??
  56. if ((!pszCabName) || (!pszExpandDir))
  57. return E_INVALIDARG;
  58. hinst = LoadLibrary("URLMON.DLL");
  59. if (hinst)
  60. {
  61. fpExtract = (EXTRACT)GetProcAddress(hinst, "Extract");
  62. if (fpExtract)
  63. {
  64. psess = (PSESSION)LocalAlloc(LPTR, sizeof(SESSION));
  65. if (psess)
  66. {
  67. lstrcpy(psess->achLocation, pszExpandDir);
  68. // Initialize the structure
  69. if (pszFileList == NULL)
  70. {
  71. // Extract all
  72. psess->flags = SESSION_FLAG_EXTRACT_ALL|SESSION_FLAG_ENUMERATE;
  73. hr = fpExtract(psess, pszCabName);
  74. // BUGBUG: What if psess->erf reports an error??
  75. }
  76. else
  77. {
  78. // I append a '/0' therefor +2
  79. pszMyFileList = (LPSTR)LocalAlloc(LPTR, lstrlen(pszFileList)+2);
  80. if (pszMyFileList)
  81. {
  82. iFiles = PrepareFileList(pszMyFileList, pszFileList);
  83. psess->flags = SESSION_FLAG_ENUMERATE;
  84. if ((iFiles > 0) &&
  85. ( !FAILED(hr = fpExtract(psess, pszCabName)) ))
  86. // What if psess->erf reports an error??
  87. {
  88. // If there are files in the list and we enumarated files
  89. // Got the list of files in the cab
  90. pfPriv = NULL;
  91. pf = psess->pFileList;
  92. while (pf != NULL )
  93. {
  94. if (!IsFileInList(pf->pszFilename, pszMyFileList))
  95. {
  96. // Delete the node from the list
  97. if (pfPriv == NULL)
  98. {
  99. // Delete the head
  100. psess->pFileList = pf->pNextName;
  101. FreeFileNode(pf);
  102. pf = psess->pFileList;
  103. }
  104. else
  105. {
  106. pfPriv->pNextName = pf->pNextName;
  107. FreeFileNode(pf);
  108. pf = pfPriv->pNextName;
  109. }
  110. }
  111. else
  112. {
  113. // Just go to the next one
  114. pfPriv = pf;
  115. pf = pf->pNextName;
  116. iFiles--;
  117. }
  118. }
  119. if ((psess->pFileList) && (iFiles == 0))
  120. {
  121. // Reset the error flag
  122. psess->erf.fError = FALSE;
  123. psess->erf.erfOper = 0;
  124. psess->pFilesToExtract = psess->pFileList;
  125. psess->flags &= ~SESSION_FLAG_ENUMERATE; // already enumerated
  126. hr = fpExtract(psess, pszCabName);
  127. // BUGBUG: What if psess->erf reports an error??
  128. }
  129. else
  130. hr = E_FAIL; // File(s) is not in cab.
  131. }
  132. LocalFree(pszMyFileList);
  133. pszMyFileList = NULL;
  134. }
  135. else
  136. hr = E_OUTOFMEMORY;
  137. }
  138. FreeFileList(psess);
  139. LocalFree(psess);
  140. psess = NULL;
  141. }
  142. else
  143. hr = E_OUTOFMEMORY;
  144. }
  145. FreeLibrary(hinst);
  146. }
  147. // Extract may only return S_FALSE in a failure case.
  148. if (!FAILED(hr) && (hr == S_FALSE))
  149. hr = E_FAIL;
  150. return (hr);
  151. }
  152. VOID FreeFileList(PSESSION psess)
  153. {
  154. PFNAME rover = psess->pFileList;
  155. PFNAME roverprev;
  156. while (rover != NULL)
  157. {
  158. roverprev = rover; // save for free'ing current rover below
  159. rover = rover->pNextName;
  160. FreeFileNode(roverprev);
  161. }
  162. psess->pFileList = NULL; // prevent use after deletion!
  163. }
  164. VOID FreeFileNode(PFNAME pfname)
  165. {
  166. CoTaskMemFree(pfname->pszFilename);
  167. CoTaskMemFree(pfname);
  168. }
  169. BOOL IsFileInList(LPSTR pszFile, LPSTR pszFileList)
  170. {
  171. char *p;
  172. int iLenFile = lstrlen(pszFile);
  173. BOOL bFound = FALSE;
  174. p = pszFileList;
  175. while ((*p != '\0') && (!bFound))
  176. {
  177. if (lstrlen(p) == iLenFile)
  178. bFound = (lstrcmpi(p, pszFile) == 0);
  179. if (!bFound)
  180. p += lstrlen(p) + 1;
  181. }
  182. return (bFound);
  183. }
  184. int PrepareFileList(LPSTR pszOutFileList, LPCSTR pszInFileList)
  185. {
  186. int iFiles = 0; // number of files in list
  187. char *p;
  188. p = (LPSTR)pszInFileList; // p is used to point into both arrays
  189. // trim leading spaces, tabs or :
  190. while ((*p == ' ') || (*p == '\t') || (*p == ':'))
  191. p++;
  192. lstrcpy(pszOutFileList, p);
  193. p = pszOutFileList;
  194. if (lstrlen(pszOutFileList) > 0)
  195. {
  196. // Only if we have atleast one character left.
  197. // This cannot be a space of tab, because we
  198. // would have removed this above.
  199. p += (lstrlen(pszOutFileList) - 1);
  200. // trim railing spaces, tabs or :
  201. while ((*p == ' ') || (*p == '\t') || (*p == ':'))
  202. p--;
  203. // Put a '\0' for the last space/tab
  204. *(++p) = '\0';
  205. }
  206. if (*pszOutFileList)
  207. {
  208. iFiles++;
  209. // Now replace ':' with '\0'
  210. p = pszOutFileList;
  211. while (*p != '\0')
  212. {
  213. if (*p == ':')
  214. {
  215. *p = '\0';
  216. iFiles++;
  217. }
  218. p++;
  219. }
  220. // Make sure we have a double '\0' at the end.
  221. *(++p) = '\0';
  222. }
  223. return iFiles;
  224. }