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.

667 lines
13 KiB

  1. /********************************************************************
  2. WRAPSTOR.CPP
  3. Owner: ErinFox
  4. Created: 28-Feb-1997
  5. Description: This file contains file system calls that are wrapped
  6. with the InfoTech IStorage implementation
  7. *********************************************************************/
  8. // For IStorage support
  9. #define INITGUID
  10. #include <windows.h>
  11. #include <basetyps.h>
  12. #include <comdef.h>
  13. #include <MSITStg.h>
  14. // InfoTech includes
  15. #include <mvopsys.h>
  16. #include <_mvutil.h>
  17. #include <wrapstor.h>
  18. #include "iofts.h"
  19. // DOSFILE support
  20. #include <io.h>
  21. #include <fcntl.h>
  22. #include <sys\types.h>
  23. #include <sys\stat.h>
  24. #define RESERVED 0
  25. // I "borrowed" these from Tome code
  26. #define PLI_To_PFO(PLI) ((FILEOFFSET *) PLI)
  27. #define LI_To_FO(LI) (*PLI_To_PFO(&LI))
  28. #define PFO_To_PLI(PFO) ((LARGE_INTEGER *) PFO)
  29. #define FO_To_LI(FO) (*PFO_To_PLI(&FO))
  30. // was in iofts.c
  31. #ifdef _DEBUG
  32. static char s_aszModule[] = __FILE__; // Used by error return functions.
  33. #endif
  34. // was in iofts.c
  35. #define OPENED_HFS (BYTE)0x80
  36. // was in iofts.c
  37. PRIVATE HANDLE NEAR PASCAL IoftsWin32Create(LPCSTR lpstr, DWORD w);
  38. PRIVATE HANDLE NEAR PASCAL IoftsWin32Open(LPCSTR lpstr, DWORD w);
  39. // was in iofts.c
  40. #define CREAT(sz, w) IoftsWin32Create(sz, w)
  41. #define OPEN(sz, w) IoftsWin32Open(sz, w)
  42. //
  43. // These functions came from subfile.c
  44. //
  45. PUBLIC HF PASCAL FAR EXPORT_API HfOpenHfs(HFS hfs, LPCWSTR wsz,
  46. BYTE bFlags, LPERRB lperrb)
  47. {
  48. HF hf;
  49. DWORD grfMode;
  50. HRESULT hr;
  51. // TODO: find out how big this really should be
  52. // OLECHAR wsz[_MAX_PATH];
  53. // MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
  54. if (bFlags & HFOPEN_READWRITE)
  55. grfMode = STGM_READWRITE;
  56. else if (bFlags & HFOPEN_READ)
  57. grfMode = STGM_READ;
  58. if (!(bFlags & HFOPEN_CREATE))
  59. {
  60. hr = hfs->OpenStream(wsz, NULL, grfMode, RESERVED, &hf);
  61. }
  62. else
  63. {
  64. hr = hfs->CreateStream(wsz, grfMode, RESERVED, RESERVED, &hf);
  65. }
  66. // make sure we pass back a NULL if open/create failed
  67. if (!SUCCEEDED(hr))
  68. hf = NULL;
  69. // sometimes we get passed NULL for lperrb
  70. if (lperrb)
  71. *lperrb = hr;
  72. return hf;
  73. }
  74. PUBLIC HF PASCAL FAR EXPORT_API HfCreateFileHfs(HFS hfs, LPCSTR sz,
  75. BYTE bFlags, LPERRB lperrb)
  76. {
  77. HF hf;
  78. DWORD grfMode;
  79. HRESULT hr;
  80. // TODO: find out how big this really should be
  81. OLECHAR wsz[_MAX_PATH];
  82. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
  83. if (bFlags & HFOPEN_READWRITE)
  84. grfMode = STGM_READWRITE;
  85. else if (bFlags & HFOPEN_READ)
  86. grfMode = STGM_READ;
  87. hr = hfs->CreateStream(wsz, grfMode, RESERVED, RESERVED, &hf);
  88. // make sure we pass back NULL if failure
  89. if (!SUCCEEDED(hr))
  90. hf = NULL;
  91. if (lperrb)
  92. *lperrb = hr;
  93. return hf;
  94. }
  95. // This is currently the same as HfOpenHfs, but once we have Ron's
  96. // enhancements to Tome we will be able to set the size on the file
  97. PUBLIC HF PASCAL FAR EXPORT_API HfOpenHfsReserve(HFS hfs, LPCSTR sz,
  98. BYTE bFlags, FILEOFFSET foReserve, LPERRB lperrb)
  99. {
  100. HF hf;
  101. DWORD grfMode;
  102. HRESULT hr;
  103. // TODO: find out how big this really should be
  104. OLECHAR wsz[_MAX_PATH];
  105. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
  106. if (bFlags & HFOPEN_READWRITE)
  107. grfMode = STGM_READWRITE;
  108. else if (bFlags & HFOPEN_READ)
  109. grfMode = STGM_READ;
  110. if (!(bFlags & HFOPEN_CREATE))
  111. {
  112. hr = hfs->OpenStream(wsz, NULL, grfMode, RESERVED, &hf);
  113. }
  114. else
  115. {
  116. hr = hfs->CreateStream(wsz, grfMode, RESERVED, RESERVED, &hf);
  117. }
  118. if (!SUCCEEDED(hr))
  119. hf = NULL;
  120. if (lperrb)
  121. *lperrb = hr;
  122. return hf;
  123. }
  124. PUBLIC LONG PASCAL FAR EXPORT_API LcbReadHf(HF hf, LPVOID lpvBuffer,
  125. LONG lcb, LPERRB lperrb)
  126. {
  127. ULONG cbRead;
  128. HRESULT hr;
  129. hr = hf->Read(lpvBuffer, lcb, &cbRead);
  130. if (lperrb)
  131. *lperrb = hr;
  132. return cbRead;
  133. }
  134. PUBLIC LONG PASCAL FAR EXPORT_API LcbWriteHf(HF hf, LPVOID lpvBuffer,
  135. LONG lcb, LPERRB lperrb)
  136. {
  137. ULONG cbWrote;
  138. HRESULT hr;
  139. hr = hf->Write(lpvBuffer, lcb, &cbWrote);
  140. if (lperrb)
  141. *lperrb = hr;
  142. return cbWrote;
  143. }
  144. PUBLIC FILEOFFSET PASCAL FAR EXPORT_API FoSeekHf(HF hf, FILEOFFSET foOffset,
  145. WORD wOrigin, LPERRB lperrb)
  146. {
  147. HRESULT hr;
  148. ULARGE_INTEGER liNewPos;
  149. LARGE_INTEGER liOffset = FO_To_LI(foOffset);
  150. hr = hf->Seek(liOffset, (DWORD)wOrigin, &liNewPos);
  151. if (lperrb)
  152. *lperrb = hr;
  153. return LI_To_FO(liNewPos);
  154. }
  155. PUBLIC RC PASCAL FAR EXPORT_API RcCloseHf(HF hf)
  156. {
  157. if (hf)
  158. hf->Release();
  159. return S_OK;
  160. }
  161. PUBLIC BOOL PASCAL FAR EXPORT_API FAccessHfs( HFS hfs, LPCSTR szName, BYTE bFlags, LPERRB lperrb)
  162. {
  163. HRESULT hr;
  164. HF hf = NULL;
  165. BOOL fRet = FALSE;
  166. if (lperrb)
  167. *lperrb = S_OK; // for now
  168. // TODO: find out how big this really should be
  169. OLECHAR wszName[_MAX_PATH];
  170. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szName, -1, wszName, _MAX_PATH);
  171. hr = hfs->OpenStream(wszName, NULL, STGM_READWRITE, RESERVED, &hf);
  172. if (S_OK == hr)
  173. {
  174. if (bFlags & FACCESS_EXISTS)
  175. fRet = TRUE;
  176. }
  177. else if (STG_E_FILENOTFOUND == hr)
  178. {
  179. SetErrCode (lperrb, E_FILENOTFOUND);
  180. }
  181. // else
  182. // {
  183. // Need to set error if anything but NOTFOUND
  184. // }
  185. if (hf)
  186. hf->Release();
  187. return fRet;
  188. }
  189. PUBLIC FILEOFFSET PASCAL FAR EXPORT_API FoSizeHf(HF hf, LPERRB lperrb)
  190. {
  191. STATSTG stat;
  192. HRESULT hr;
  193. FILEOFFSET foSize;
  194. hr = hf->Stat(&stat, STATFLAG_NONAME);
  195. if (S_OK == hr)
  196. foSize = LI_To_FO(stat.cbSize);
  197. else
  198. foSize = foNil;
  199. if (lperrb)
  200. *lperrb = hr;
  201. return foSize;
  202. }
  203. ///////////////////////////////////////////////////////////////////
  204. // These functions came from iofts.c
  205. ///////////////////////////////////////////////////////////////////
  206. PUBLIC HFPB FAR PASCAL FileCreate (HFPB hfpbSysFile, LPCSTR lszFilename,
  207. int fFileType, LPERRB lperrb)
  208. {
  209. LPFPB lpfpb; /* Pointer to file parameter block */
  210. HANDLE hMem;
  211. HFPB hfpb;
  212. HRESULT hr;
  213. OLECHAR wszFileName[_MAX_PATH];
  214. FM fm;
  215. HFS hfs;
  216. /* Check for valid filename */
  217. if (lszFilename == NULL )
  218. {
  219. SetErrCode (lperrb, E_INVALIDARG);
  220. return 0;
  221. }
  222. /* Allocate a file's parameter block */
  223. if (!(hMem = _GLOBALALLOC(GMEM_ZEROINIT, sizeof(FPB))))
  224. {
  225. SetErrCode(lperrb, E_OUTOFMEMORY);
  226. return NULL;
  227. }
  228. if (!(lpfpb = (LPFPB)_GLOBALLOCK(hMem)))
  229. {
  230. _GLOBALUNLOCK(hMem);
  231. SetErrCode(lperrb,E_OUTOFMEMORY);
  232. return NULL;
  233. }
  234. _INITIALIZECRITICALSECTION(&lpfpb->cs);
  235. lpfpb->hStruct = hMem;
  236. switch (fFileType)
  237. {
  238. case FS_SYSTEMFILE:
  239. IClassFactory* pCF;
  240. hr = CoGetClassObject(CLSID_ITStorage, CLSCTX_INPROC_SERVER, NULL,
  241. IID_IClassFactory, (VOID **)&pCF);
  242. // Error check!
  243. IITStorage* pITStorage;
  244. hr = pCF->CreateInstance(NULL, IID_ITStorage,
  245. (VOID **)&pITStorage);
  246. if (pCF)
  247. pCF->Release();
  248. fm = FmNewSzDir((LPSTR)lszFilename, dirCurrent, NULL);
  249. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fm, -1, wszFileName, _MAX_PATH);
  250. hr = pITStorage->StgCreateDocfile(wszFileName, STGM_READWRITE, RESERVED, &hfs);
  251. // if call failed, make sure to set hfs NULL
  252. if (!SUCCEEDED(hr))
  253. {
  254. hfs = NULL;
  255. SetErrCode(lperrb, hr);
  256. }
  257. lpfpb->fs.hfs = hfs;
  258. if (pITStorage)
  259. pITStorage->Release();
  260. DisposeFm(fm);
  261. break;
  262. case FS_SUBFILE:
  263. hfs = GetHfs(hfpbSysFile,lszFilename,TRUE,lperrb);
  264. if (hfs)
  265. {
  266. lpfpb->fs.hf = HfCreateFileHfs(hfs,GetSubFilename(lszFilename,
  267. NULL),HFOPEN_READWRITE,lperrb);
  268. lpfpb->ioMode = OF_READWRITE;
  269. if (lpfpb->fs.hf == NULL)
  270. {
  271. if (!hfpbSysFile)
  272. RcCloseHfs(hfs);
  273. goto ErrorExit;
  274. }
  275. else
  276. {
  277. if (!hfpbSysFile)
  278. lpfpb->ioMode |= OPENED_HFS;
  279. }
  280. }
  281. else
  282. {
  283. goto ErrorExit;
  284. }
  285. break;
  286. case REGULAR_FILE:
  287. // Create the file
  288. if ((lpfpb->fs.hFile = (HFILE_GENERIC)CREAT (lszFilename, 0))
  289. == HFILE_GENERIC_ERROR)
  290. {
  291. SetErrCode(lperrb,E_FILECREATE);
  292. goto ErrorExit;
  293. }
  294. lpfpb->ioMode = OF_READWRITE;
  295. break;
  296. }
  297. // Set the filetype
  298. lpfpb->fFileType = (BYTE) fFileType;
  299. _GLOBALUNLOCK(hfpb = lpfpb->hStruct);
  300. return hfpb;
  301. ErrorExit:
  302. _DELETECRITICALSECTION(&lpfpb->cs);
  303. _GLOBALFREE(hMem);
  304. return 0;
  305. }
  306. PUBLIC HFPB FAR PASCAL FileOpen (HFPB hfpbSysFile, LPCSTR lszFilename,
  307. int fFileType, int ioMode, LPERRB lperrb)
  308. {
  309. LPFPB lpfpb; /* Pointer to file parameter block */
  310. HANDLE hMem;
  311. HFPB hfpb;
  312. FM fm;
  313. OLECHAR wszFileName[_MAX_PATH];
  314. HFS hfs;
  315. HRESULT hr;
  316. /* Check for valid filename */
  317. if (lszFilename == NULL )
  318. {
  319. SetErrCode (lperrb, E_INVALIDARG);
  320. return 0;
  321. }
  322. /* Allocate a file's parameter block */
  323. if (!(hMem = _GLOBALALLOC(GMEM_ZEROINIT, sizeof(FPB))))
  324. {
  325. SetErrCode(lperrb,E_OUTOFMEMORY);
  326. return NULL;
  327. }
  328. if (!(lpfpb = (LPFPB)_GLOBALLOCK(hMem)))
  329. {
  330. _GLOBALUNLOCK(hMem);
  331. SetErrCode(lperrb,E_OUTOFMEMORY);
  332. return NULL;
  333. }
  334. _INITIALIZECRITICALSECTION(&lpfpb->cs);
  335. lpfpb->hStruct = hMem;
  336. switch (fFileType)
  337. {
  338. case FS_SYSTEMFILE:
  339. IClassFactory* pCF;
  340. hr = CoGetClassObject(CLSID_ITStorage, CLSCTX_INPROC_SERVER, NULL,
  341. IID_IClassFactory, (VOID **)&pCF);
  342. // Error check!
  343. IITStorage* pITStorage;
  344. hr = pCF->CreateInstance(NULL, IID_ITStorage,
  345. (VOID **)&pITStorage);
  346. if (pCF)
  347. pCF->Release();
  348. fm = FmNewSzDir((LPSTR)lszFilename, dirCurrent, NULL);
  349. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fm, -1, wszFileName, _MAX_PATH);
  350. hr = pITStorage->StgOpenStorage(wszFileName, NULL, (ioMode==READ) ? STGM_READ:STGM_READWRITE,
  351. NULL, RESERVED, &hfs);
  352. if (!SUCCEEDED(hr))
  353. {
  354. hfs = NULL;
  355. SetErrCode(lperrb, hr);
  356. }
  357. lpfpb->fs.hfs = hfs;
  358. if (pITStorage)
  359. pITStorage->Release();
  360. DisposeFm(fm);
  361. break;
  362. case FS_SUBFILE:
  363. hfs = GetHfs(hfpbSysFile,lszFilename,FALSE,lperrb);
  364. if (hfs)
  365. {
  366. OLECHAR wsz[_MAX_PATH];
  367. LPCSTR sz = GetSubFilename(lszFilename, NULL);
  368. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
  369. lpfpb->fs.hf = HfOpenHfs(hfs, wsz,
  370. (BYTE)((ioMode==READ)?HFOPEN_READ:HFOPEN_READWRITE),lperrb);
  371. lpfpb->ioMode = (BYTE) ioMode;
  372. if (lpfpb->fs.hf == 0)
  373. {
  374. if (!hfpbSysFile)
  375. RcCloseHfs(hfs);
  376. SetErrCode (lperrb, E_NOTEXIST);
  377. goto ErrorExit;
  378. }
  379. else
  380. {
  381. if (!hfpbSysFile)
  382. lpfpb->ioMode|=OPENED_HFS;
  383. }
  384. }
  385. else
  386. {
  387. SetErrCode (lperrb, E_NOTEXIST);
  388. goto ErrorExit;
  389. }
  390. break;
  391. case REGULAR_FILE:
  392. /* Set the IO mode and appropriate error messages */
  393. if (ioMode == READ)
  394. {
  395. /* Open the file */
  396. if ((lpfpb->fs.hFile = (HFILE_GENERIC)OPEN (lszFilename,
  397. ioMode)) == HFILE_GENERIC_ERROR)
  398. {
  399. SetErrCode(lperrb,E_NOTEXIST);
  400. goto ErrorExit;
  401. }
  402. }
  403. else
  404. {
  405. ioMode = OF_READWRITE;
  406. /* Open the file */
  407. if ((lpfpb->fs.hFile = (HFILE_GENERIC)OPEN(lszFilename, ioMode))
  408. == HFILE_GENERIC_ERROR)
  409. {
  410. SetErrCode(lperrb,E_FILECREATE);
  411. goto ErrorExit;
  412. }
  413. }
  414. lpfpb->ioMode = (BYTE) ioMode;
  415. break;
  416. }
  417. // set filetype
  418. lpfpb->fFileType = (BYTE) fFileType;
  419. _GLOBALUNLOCK(hfpb = lpfpb->hStruct);
  420. return hfpb;
  421. ErrorExit:
  422. _DELETECRITICALSECTION(&lpfpb->cs);
  423. _GLOBALFREE(hMem);
  424. return 0;
  425. }
  426. PUBLIC RC FAR PASCAL FileClose(HFPB hfpb)
  427. {
  428. RC rc;
  429. LPFPB lpfpb;
  430. if (hfpb == NULL)
  431. return E_HANDLE;
  432. lpfpb = (LPFPB)_GLOBALLOCK(hfpb);
  433. _ENTERCRITICALSECTION(&lpfpb->cs);
  434. rc = S_OK;
  435. switch (lpfpb->fFileType)
  436. {
  437. case FS_SYSTEMFILE:
  438. if (lpfpb->fs.hfs)
  439. lpfpb->fs.hfs->Release();
  440. break;
  441. case FS_SUBFILE:
  442. if (lpfpb->fs.hf)
  443. lpfpb->fs.hf->Release();
  444. break;
  445. case REGULAR_FILE:
  446. if (lpfpb->fs.hFile)
  447. rc = (!CloseHandle(lpfpb->fs.hFile))?E_FILECLOSE:S_OK;
  448. break;
  449. }
  450. /* Free the file parameter block structure */
  451. _LEAVECRITICALSECTION(&lpfpb->cs);
  452. _DELETECRITICALSECTION(&lpfpb->cs);
  453. _GLOBALUNLOCK(hfpb);
  454. _GLOBALFREE(hfpb);
  455. return rc;
  456. }
  457. // These are verbatim from iofts.c. I put them here so we can compile
  458. PRIVATE HANDLE NEAR PASCAL IoftsWin32Create(LPCSTR lpstr, DWORD w)
  459. {
  460. SECURITY_ATTRIBUTES sa;
  461. HANDLE hfile;
  462. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  463. sa.lpSecurityDescriptor = NULL;
  464. sa.bInheritHandle = 0;
  465. hfile= CreateFile(lpstr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
  466. &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  467. return hfile;
  468. }
  469. PRIVATE HANDLE NEAR PASCAL IoftsWin32Open(LPCSTR lpstr, DWORD w)
  470. {
  471. SECURITY_ATTRIBUTES sa;
  472. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  473. sa.lpSecurityDescriptor = NULL;
  474. sa.bInheritHandle = 0;
  475. return CreateFile(lpstr, (w == READ) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
  476. FILE_SHARE_READ, &sa,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  477. }
  478. #if 0
  479. // This is new functionality
  480. PUBLIC FM EXPORT_API FAR PASCAL FmFromHfs(HFS hfs)
  481. {
  482. char szStoreName[_MAX_PATH];
  483. FM fm;
  484. ERRB errb;
  485. STATSTG StoreStat;
  486. HRESULT hr;
  487. // get storage name
  488. // Turns out this isn't IMPLEMENTED yet!
  489. hr = hfs->Stat(&StoreStat, STATFLAG_DEFAULT);
  490. if (S_OK == hr)
  491. {
  492. // and convert it since FMs aren't Unicode
  493. WideCharToMultiByte(CP_ACP, 0, StoreStat.pwcsName, -1,
  494. szStoreName, _MAX_PATH, NULL, NULL);
  495. // free memory associated with pwcsName
  496. CoTaskMemFree(StoreStat.pwcsName);
  497. // create new FM
  498. fm = FmNew(szStoreName, &errb);
  499. }
  500. else
  501. fm = NULL;
  502. return fm;
  503. }
  504. #endif