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.

321 lines
8.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: refilb.cxx
  7. //
  8. // Contents: Reference ILockBytes class
  9. //
  10. // Classes: CFileILB
  11. //
  12. // Notes: This Class always call single byte I/O routines
  13. // because most systems only have support for single byte
  14. // I/O. This makes the code more portable.
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <errno.h>
  18. #include "refilb.hxx"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <sys/stat.h>
  23. #include "time.hxx"
  24. #ifdef _WIN32
  25. #include <io.h> // to get definition of wunlink
  26. #else
  27. #include <unistd.h>
  28. #define _stat stat
  29. #define _tstat stat
  30. #endif
  31. #include <stdlib.h>
  32. #include <assert.h>
  33. #ifdef PRINT_TRACE
  34. #define TRACE(x) printf(x)
  35. #else
  36. #define TRACE(x)
  37. #endif
  38. static int filenum = 0;
  39. char * GetTempFileName(void)
  40. {
  41. char *psz = new char[_MAX_PATH +1];
  42. strcpy(psz, "dft");
  43. _itoa(filenum, psz + 3, 10);
  44. filenum++;
  45. return psz;
  46. }
  47. CFileILB::CFileILB(const TCHAR *pszName,
  48. DWORD grfMode,
  49. BOOL fOpenFile/* =TRUE */)
  50. {
  51. _pszName = NULL;
  52. _fDelete = FALSE;
  53. if (pszName == NULL)
  54. {
  55. _pszName = GetTempFileName();
  56. _unlink(_pszName); // make sure file is over written
  57. _fDelete |= ILB_DELETEONERR; // don't want to keep scratch files
  58. }
  59. else
  60. {
  61. _pszName = new char[_MAX_PATH + 1];
  62. TTOS(pszName, _pszName, _tcslen(pszName)+1);
  63. }
  64. if (grfMode & STGM_DELETEONRELEASE)
  65. _fDelete |= ILB_DELETEONRELEASE;
  66. _f = NULL;
  67. if (fOpenFile)
  68. {
  69. // disregard if file is already there
  70. Create(STGM_CREATE|STGM_READWRITE);
  71. // got to open the file with this option
  72. assert(_f && "CFileILB could not open the file!");
  73. }
  74. _ulRef = 1;
  75. }
  76. static const char pcszReadOnly[] ="rb";
  77. static const char pcszReadWrite[] = "r+b";
  78. static const char pcszWrite[] = "w+b";
  79. SCODE CFileILB::Create(DWORD grfMode)
  80. {
  81. char const *pszMode = pcszReadOnly; // default
  82. if (grfMode & STGM_READWRITE)
  83. pszMode = pcszReadWrite;
  84. else
  85. TRACE("CFileILB::Create called with Read Only!!\n");
  86. _f = fopen(_pszName, pszMode);
  87. if (_f) // open succeeded
  88. {
  89. if ((grfMode & (STGM_CREATE|STGM_CONVERT) ) == STGM_FAILIFTHERE)
  90. return STG_E_FILEALREADYEXISTS;
  91. }
  92. else if (errno==EACCES && (grfMode & STGM_CONVERT))
  93. {
  94. TRACE("Access Denied in CFileILB::Create\n");
  95. return STG_E_ACCESSDENIED;
  96. }
  97. else
  98. {
  99. // the file does not exists, create the file
  100. _f = fopen(_pszName, pcszWrite);
  101. if (_f==NULL)
  102. {
  103. // we could not create the file for some reason
  104. // return the appropriate error code
  105. if (errno== EACCES)
  106. return STG_E_ACCESSDENIED;
  107. else
  108. {
  109. return STG_E_INVALIDNAME; // assume it is an invalid name
  110. }
  111. }
  112. else
  113. {
  114. // the newly create file should be deleted on error
  115. _fDelete |= ILB_DELETEONERR;
  116. }
  117. }
  118. return S_OK;
  119. }
  120. SCODE CFileILB::Open(DWORD grfMode)
  121. {
  122. char const *pszMode = pcszReadOnly; // default
  123. assert( (_fDelete & ILB_DELETEONERR)==0 ); // this means an null named file
  124. // has been opened
  125. if (grfMode & STGM_READWRITE)
  126. pszMode = pcszReadWrite;
  127. else
  128. TRACE( "CFileILB::Open called with Read Only!!\n");
  129. _f = fopen(_pszName, pszMode);
  130. if (_f == NULL)
  131. {
  132. if (errno==EACCES) return STG_E_ACCESSDENIED;
  133. else if (errno==ENOENT) return STG_E_FILENOTFOUND;
  134. else return STG_E_INVALIDNAME; // we assume that the name is invalid
  135. }
  136. return S_OK;
  137. }
  138. CFileILB::~CFileILB()
  139. {
  140. if (_f)
  141. fclose(_f);
  142. if (_fDelete & ILB_DELETEONRELEASE)
  143. {
  144. // nothing we can do if the file cannot be deleted somehow
  145. // since the ref impl. is not multi-thread safe
  146. _unlink(_pszName);
  147. }
  148. delete _pszName;
  149. }
  150. STDMETHODIMP CFileILB::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  151. {
  152. *ppvObj = NULL;
  153. UNREFERENCED_PARM(riid);
  154. //olAssert(FALSE && "function not implemented!");
  155. return ResultFromScode(STG_E_INVALIDFUNCTION);
  156. }
  157. STDMETHODIMP_(ULONG) CFileILB::AddRef(void)
  158. {
  159. _ulRef++;
  160. return(_ulRef);
  161. }
  162. STDMETHODIMP_(ULONG) CFileILB::Release(void)
  163. {
  164. _ulRef--;
  165. TRACE("CFileILB::Release%lx\n");
  166. if (_ulRef > 0)
  167. return(_ulRef);
  168. delete this;
  169. return(0);
  170. }
  171. ULONG CFileILB::ReleaseOnError(void)
  172. {
  173. // this function should be not used otherwise
  174. assert(_ulRef == 1);
  175. // Delete the file if it is a file we just created
  176. if (_fDelete & ILB_DELETEONERR)
  177. _fDelete |= ILB_DELETEONRELEASE;
  178. return( Release() );
  179. }
  180. STDMETHODIMP CFileILB::ReadAt(ULARGE_INTEGER ulPosition,
  181. VOID HUGEP *pb,
  182. ULONG cb,
  183. ULONG *pcbRead)
  184. {
  185. fseek(_f, ulPosition.QuadPart, SEEK_SET);
  186. *pcbRead = fread(pb, 1, cb, _f);
  187. return NOERROR;
  188. }
  189. STDMETHODIMP CFileILB::WriteAt(ULARGE_INTEGER ulPosition,
  190. VOID const HUGEP *pb,
  191. ULONG cb,
  192. ULONG FAR *pcbWritten)
  193. {
  194. fseek(_f, ulPosition.QuadPart, SEEK_SET);
  195. *pcbWritten = fwrite(pb, 1, cb, _f);
  196. return NOERROR;
  197. }
  198. STDMETHODIMP CFileILB::Flush(void)
  199. {
  200. fflush(_f);
  201. return NOERROR;
  202. }
  203. STDMETHODIMP CFileILB::SetSize(ULARGE_INTEGER ulNewSize)
  204. {
  205. LONGLONG cbNewSize = ulNewSize.QuadPart;
  206. LONGLONG cbCurrentSize = ftell(_f);
  207. if(-1 == cbCurrentSize)
  208. return STG_E_SEEKERROR;
  209. if(cbCurrentSize < cbNewSize)
  210. { // Increase the Size
  211. fseek(_f, cbNewSize-1, SEEK_SET);
  212. if(1 != fwrite("", 1, 1, _f))
  213. return STG_E_WRITEFAULT;
  214. }
  215. else if(cbCurrentSize > cbNewSize)
  216. { // Decrease the Size
  217. // OS specific: file truncation.
  218. }
  219. return NOERROR;
  220. }
  221. STDMETHODIMP CFileILB::LockRegion(ULARGE_INTEGER libOffset,
  222. ULARGE_INTEGER cb,
  223. DWORD dwLockType)
  224. {
  225. UNREFERENCED_PARM(dwLockType);
  226. UNREFERENCED_PARM(cb);
  227. UNREFERENCED_PARM(libOffset);
  228. assert(FALSE && "function not implemented!");
  229. return ResultFromScode(STG_E_INVALIDFUNCTION);
  230. }
  231. STDMETHODIMP CFileILB::UnlockRegion(ULARGE_INTEGER libOffset,
  232. ULARGE_INTEGER cb,
  233. DWORD dwLockType)
  234. {
  235. UNREFERENCED_PARM(dwLockType);
  236. UNREFERENCED_PARM(cb);
  237. UNREFERENCED_PARM(libOffset);
  238. assert(FALSE && "function not implemented!");
  239. return ResultFromScode(STG_E_INVALIDFUNCTION);
  240. }
  241. STDMETHODIMP CFileILB::Stat(STATSTG FAR *pstatstg, DWORD grfStatFlag)
  242. {
  243. memset(pstatstg, 0, sizeof(STATSTG));
  244. if ((grfStatFlag & STATFLAG_NONAME) == 0)
  245. {
  246. char pchTemp[_MAX_PATH+1];
  247. _fullpath(pchTemp, _pszName, _MAX_PATH+1);
  248. pstatstg->pwcsName = new TCHAR[strlen(pchTemp)+1];
  249. STOT(pchTemp, pstatstg->pwcsName, strlen(pchTemp)+1);
  250. }
  251. pstatstg->type = STGTY_LOCKBYTES;
  252. fseek(_f, 0, SEEK_END);
  253. (pstatstg->cbSize).QuadPart = ftell(_f);
  254. // just return a default, the function that calls this should fill in
  255. // the structure.
  256. pstatstg->grfMode = STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE;
  257. struct _stat buf;
  258. int result = _stat(_pszName, &buf);
  259. if (!result) // fill in zeros
  260. {
  261. pstatstg->atime.dwLowDateTime = pstatstg->atime.dwLowDateTime = 0;
  262. pstatstg->mtime.dwLowDateTime = pstatstg->mtime.dwLowDateTime = 0;
  263. pstatstg->ctime.dwLowDateTime = pstatstg->ctime.dwLowDateTime = 0;
  264. }
  265. else
  266. {
  267. TimeTToFileTime(&buf.st_atime, &pstatstg->atime);
  268. TimeTToFileTime(&buf.st_mtime, &pstatstg->mtime);
  269. TimeTToFileTime(&buf.st_ctime, &pstatstg->ctime);
  270. }
  271. return NOERROR;
  272. }
  273. EXTERN_C STDAPI_(BOOL) IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
  274. {
  275. return (memcmp(&rguid1, &rguid2, sizeof(GUID)) == 0);
  276. }