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.

391 lines
10 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: funcs.cxx
  7. //
  8. // Contents: Generic DocFile support functions
  9. //
  10. // Functions: ModeToTFlags
  11. // CheckName
  12. // wcsdup
  13. // VerifyPerms
  14. //
  15. //---------------------------------------------------------------
  16. #include "dfhead.cxx"
  17. //+--------------------------------------------------------------
  18. //
  19. // Function: ModeToDFlags, private
  20. //
  21. // Synopsis: Translates STGM flags to DF flags
  22. //
  23. // Arguments: [dwModeFlags]
  24. //
  25. // Returns: DF_*
  26. //
  27. //---------------------------------------------------------------
  28. DFLAGS ModeToDFlags(DWORD const dwModeFlags)
  29. {
  30. DFLAGS df;
  31. olDebugOut((DEB_ITRACE, "In ModeToDFlags(%lX)\n", dwModeFlags));
  32. if ((dwModeFlags & STGM_TRANSACTED) == 0)
  33. df = DF_DIRECT;
  34. else
  35. df = DF_TRANSACTED;
  36. if ((dwModeFlags & STGM_TRANSACTED) &&
  37. (dwModeFlags & STGM_PRIORITY) == 0 &&
  38. (dwModeFlags & STGM_DENY) != STGM_SHARE_DENY_WRITE &&
  39. (dwModeFlags & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
  40. df |= DF_INDEPENDENT;
  41. switch(dwModeFlags & STGM_RDWR)
  42. {
  43. case STGM_READ:
  44. df |= DF_READ;
  45. break;
  46. case STGM_WRITE:
  47. df |= DF_WRITE;
  48. break;
  49. case STGM_READWRITE:
  50. df |= DF_READWRITE;
  51. break;
  52. default:
  53. olAssert(FALSE);
  54. break;
  55. }
  56. switch(dwModeFlags & STGM_DENY)
  57. {
  58. case STGM_SHARE_DENY_READ:
  59. df |= DF_DENYREAD;
  60. break;
  61. case STGM_SHARE_DENY_WRITE:
  62. df |= DF_DENYWRITE;
  63. break;
  64. case STGM_SHARE_EXCLUSIVE:
  65. df |= DF_DENYALL;
  66. break;
  67. // Default is deny none
  68. }
  69. if (dwModeFlags & STGM_PRIORITY)
  70. df |= DF_PRIORITY;
  71. olDebugOut((DEB_ITRACE, "Out ModeToDFlags => %lX\n", df));
  72. return df;
  73. }
  74. //+--------------------------------------------------------------
  75. //
  76. // Function: DFlagsToMode, private
  77. //
  78. // Synopsis: Converts the read/write/denials/transacted/priority
  79. // to STGM flags
  80. //
  81. // Arguments: [df] - DFlags
  82. //
  83. // Returns: STGM flags
  84. //
  85. //---------------------------------------------------------------
  86. DWORD DFlagsToMode(DFLAGS const df)
  87. {
  88. DWORD dwMode;
  89. olDebugOut((DEB_ITRACE, "In DFlagsToMode(%X)\n", df));
  90. if (P_READ(df))
  91. if (P_WRITE(df))
  92. dwMode = STGM_READWRITE;
  93. else
  94. dwMode = STGM_READ;
  95. else if (P_WRITE(df))
  96. dwMode = STGM_WRITE;
  97. // Must have either read or write, so no else
  98. if (P_DENYREAD(df))
  99. if (P_DENYWRITE(df))
  100. dwMode |= STGM_SHARE_EXCLUSIVE;
  101. else
  102. dwMode |= STGM_SHARE_DENY_READ;
  103. else if (P_DENYWRITE(df))
  104. dwMode |= STGM_SHARE_DENY_WRITE;
  105. else
  106. dwMode |= STGM_SHARE_DENY_NONE;
  107. if (P_TRANSACTED(df))
  108. dwMode |= STGM_TRANSACTED;
  109. if (P_PRIORITY(df))
  110. dwMode |= STGM_PRIORITY;
  111. olDebugOut((DEB_ITRACE, "Out DFlagsToMode\n"));
  112. return dwMode;
  113. }
  114. //+--------------------------------------------------------------
  115. //
  116. // Function: VerifyPerms, private
  117. //
  118. // Synopsis: Checks flags to see if they are valid
  119. //
  120. // Arguments: [grfMode] - Permissions
  121. //
  122. // Returns: Appropriate status code
  123. //
  124. //---------------------------------------------------------------
  125. SCODE VerifyPerms(DWORD grfMode)
  126. {
  127. SCODE sc = S_OK;
  128. olDebugOut((DEB_ITRACE, "In VerifyPerms(%lX)\n", grfMode));
  129. // Check for valid flags
  130. if ((grfMode & STGM_RDWR) > STGM_READWRITE ||
  131. (grfMode & STGM_DENY) > STGM_SHARE_DENY_NONE ||
  132. (grfMode & ~(STGM_RDWR | STGM_DENY | STGM_DIRECT | STGM_TRANSACTED |
  133. STGM_PRIORITY | STGM_CREATE | STGM_CONVERT |
  134. STGM_FAILIFTHERE | STGM_DELETEONRELEASE)))
  135. olErr(EH_Err, STG_E_INVALIDFLAG);
  136. // We don't support these modes
  137. if (grfMode & (STGM_PRIORITY|STGM_TRANSACTED|STGM_SIMPLE))
  138. {
  139. olAssert( FALSE &&
  140. aMsg("Unsupported feature of reference implemention called"));
  141. return STG_E_INVALIDFUNCTION;
  142. }
  143. // Check to make sure only one existence flag is specified
  144. // FAILIFTHERE is zero so it can't be checked
  145. if ((grfMode & (STGM_CREATE | STGM_CONVERT)) ==
  146. (STGM_CREATE | STGM_CONVERT))
  147. olErr(EH_Err, STG_E_INVALIDFLAG);
  148. // If not transacted and not priority, you can either be
  149. // read-only deny write or read-write deny all
  150. if ((grfMode & (STGM_TRANSACTED | STGM_PRIORITY)) == 0)
  151. {
  152. if ((grfMode & STGM_RDWR) == STGM_READ)
  153. {
  154. // we're asking for read-only access
  155. if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE &&
  156. (grfMode & STGM_DENY) != STGM_SHARE_DENY_WRITE)
  157. {
  158. // Can't allow others to have write access
  159. olErr(EH_Err, STG_E_INVALIDFLAG);
  160. }
  161. }
  162. else
  163. {
  164. // we're asking for write access
  165. if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
  166. {
  167. // Can't allow others to have any access
  168. olErr(EH_Err, STG_E_INVALIDFLAG);
  169. }
  170. }
  171. }
  172. olDebugOut((DEB_ITRACE, "Out VerifyPerms\n"));
  173. // Fall through
  174. EH_Err:
  175. return sc;
  176. }
  177. //+--------------------------------------------------------------
  178. //
  179. // Function: wcsdup, public
  180. //
  181. // Synopsis: Duplicates a WCHAR string
  182. //
  183. // Arguments: [pwcs] - String
  184. //
  185. // Returns: Pointer to new string or Appropriate status code
  186. //
  187. //---------------------------------------------------------------
  188. WCHAR * __cdecl wcsdup(WCHAR const *pwcs)
  189. {
  190. WCHAR *pwcsNew;
  191. olDebugOut((DEB_ITRACE, "In wcsdup(%ws)\n", pwcs));
  192. pwcsNew = new WCHAR[wcslen(pwcs)+1];
  193. if (pwcsNew == NULL)
  194. return NULL;
  195. wcscpy(pwcsNew, pwcs);
  196. olDebugOut((DEB_ITRACE, "Out wcsdup => %p\n", pwcsNew));
  197. return pwcsNew;
  198. }
  199. //+--------------------------------------------------------------
  200. //
  201. // Function: ValidateSNBW
  202. //
  203. // Synopsis: Validates SNB memory
  204. //
  205. // Arguments: [snb] - SNB
  206. //
  207. // Returns: Appropriate status code
  208. //
  209. //---------------------------------------------------------------
  210. #ifdef _UNICODE
  211. SCODE ValidateSNBW(SNBW snb)
  212. {
  213. SCODE sc;
  214. olDebugOut((DEB_ITRACE, "In ValidateSNB(%p)\n", snb));
  215. for (;;)
  216. {
  217. olChk(ValidatePtrBuffer(snb));
  218. if (*snb == NULL)
  219. break;
  220. olChk(ValidateNameW(*snb, CWCMAXPATHCOMPLEN));
  221. snb++;
  222. }
  223. olDebugOut((DEB_ITRACE, "Out ValidateSNB\n"));
  224. return S_OK;
  225. EH_Err:
  226. return sc;
  227. }
  228. #endif // ifdef _UNICODE
  229. //+--------------------------------------------------------------
  230. //
  231. // Function: CheckWName, public
  232. //
  233. // Synopsis: Checks name for illegal characters and length
  234. //
  235. // Arguments: [pwcsName] - Name
  236. //
  237. // Returns: Appropriate status code
  238. //
  239. //---------------------------------------------------------------
  240. #ifdef _UNICODE
  241. WCHAR wcsInvalid[] = { '\\', '/', ':', '!','\0' };
  242. SCODE CheckWName(WCHAR const *pwcsName)
  243. {
  244. SCODE sc;
  245. olDebugOut((DEB_ITRACE, "In CheckWName(%s)\n", pwcsName));
  246. if (FAILED(sc = ValidateNameW(pwcsName, CBMAXPATHCOMPLEN)))
  247. return sc;
  248. // >= is used because the max len includes the null terminator
  249. if (wcslen(pwcsName) >= CWCMAXPATHCOMPLEN)
  250. return STG_E_INVALIDNAME;
  251. for (; *pwcsName; pwcsName++)
  252. {
  253. if ( wcschr(wcsInvalid, *pwcsName) )
  254. return STG_E_INVALIDNAME;
  255. }
  256. olDebugOut((DEB_ITRACE, "Out CheckWName\n"));
  257. return S_OK;
  258. }
  259. #else // validation done in ascii layer already
  260. #define CheckWName(pwcsName) (S_OK)
  261. #endif // ifdef _UNICODE
  262. //+--------------------------------------------------------------
  263. //
  264. // Function: CopyDStreamToDStream
  265. //
  266. // Synopsis: Copies the contents of a stream to another stream
  267. //
  268. // Arguments: [pstFrom] - Stream to copy from
  269. // [pstTo] - Stream to copy to
  270. //
  271. // Returns: Appropriate status code
  272. //
  273. // Notes: This function may fail due to out of memory. It
  274. // may not be used by callers who must not fail due
  275. // to out of memory.
  276. //
  277. // This function does not check permissions
  278. // for write in the to streams.
  279. //
  280. //---------------------------------------------------------------
  281. SCODE CopyStreamToStream(CDirectStream *pstFrom,
  282. CDirectStream *pstTo)
  283. {
  284. BYTE *pbBuffer;
  285. SCODE sc;
  286. ULONG cbRead, cbWritten;
  287. ULONGLONG cbSize, cbPos;
  288. // Set destination size for contiguity
  289. pstFrom->GetSize(&cbSize);
  290. olChk(pstTo->SetSize(cbSize));
  291. // We're allowed to fail due to out of memory
  292. olMem(pbBuffer = new BYTE[STREAMBUFFERSIZE]);
  293. // Copy between streams
  294. cbPos = 0;
  295. for (;;)
  296. {
  297. olChkTo(EH_pbBuffer,
  298. pstFrom->ReadAt(cbPos, pbBuffer, STREAMBUFFERSIZE,
  299. (ULONG STACKBASED *)&cbRead));
  300. if (cbRead == 0) // EOF
  301. break;
  302. olChkTo(EH_pbBuffer,
  303. pstTo->WriteAt(cbPos, pbBuffer, cbRead,
  304. (ULONG STACKBASED *)&cbWritten));
  305. if (cbRead != cbWritten)
  306. olErr(EH_Err, STG_E_WRITEFAULT);
  307. cbPos += cbWritten;
  308. }
  309. delete pbBuffer;
  310. return S_OK;
  311. EH_pbBuffer:
  312. delete pbBuffer;
  313. EH_Err:
  314. return sc;
  315. }
  316. //+--------------------------------------------------------------
  317. //
  318. // Function: NameInSNB, private
  319. //
  320. // Synopsis: Determines whether the given name is in the SNB
  321. //
  322. // Arguments: [dfn] - Name
  323. // [snb] - SNB
  324. //
  325. // Returns: S_OK or S_FALSE
  326. //
  327. //---------------------------------------------------------------
  328. SCODE NameInSNB(CDfName const *dfn, SNBW snb)
  329. {
  330. SCODE sc = S_FALSE;
  331. olDebugOut((DEB_ITRACE, "In NameInSNB(%ws, %p)\n", dfn, snb));
  332. TRY
  333. {
  334. for (; *snb; snb++)
  335. if (dfwcsnicmp((WCHAR *)dfn->GetBuffer(), (WCHAR *)*snb,
  336. dfn->GetLength()) == 0)
  337. {
  338. sc = S_OK;
  339. break;
  340. }
  341. }
  342. CATCH(CException, e)
  343. {
  344. sc = e.GetErrorCode();
  345. }
  346. END_CATCH
  347. olDebugOut((DEB_ITRACE, "Out NameInSNB\n"));
  348. return sc;
  349. }