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.

335 lines
8.1 KiB

  1. #include "stdinc.h"
  2. #include "st.h"
  3. #include "filestream.cpp"
  4. #include "cresourcestream.cpp"
  5. #include "cmemorystream.cpp"
  6. BOOL
  7. WaitForThreadResumeEvent()
  8. {
  9. BOOL fResult = FALSE;
  10. InterlockedIncrement(&ThreadsWaiting);
  11. const DWORD dwWaitResult = WaitForSingleObject(ResumeThreadsEvent, INFINITE);
  12. switch (dwWaitResult)
  13. {
  14. case WAIT_OBJECT_0:
  15. fResult = true;
  16. break;
  17. default:
  18. ::FusionpSetLastWin32Error(dwWaitResult);
  19. case WAIT_FAILED:
  20. ::ReportFailure("Failed WaitForStartingEvent.WaitForSingleObject");
  21. }
  22. return fResult;
  23. }
  24. LONG StringToNumber(PCWSTR s)
  25. {
  26. int Base = 0;
  27. if (s == NULL || s[0] == 0)
  28. return 0;
  29. if (s[0] == '#')
  30. {
  31. Base = 10;
  32. ++s;
  33. }
  34. return wcstol(s, NULL, Base);
  35. }
  36. PCWSTR StringToResourceString(PCWSTR s)
  37. {
  38. if (s == NULL || s[0] == 0)
  39. return 0;
  40. if (s[0] == '#')
  41. {
  42. return reinterpret_cast<PCWSTR>(static_cast<ULONG_PTR>(StringToNumber(s)));
  43. }
  44. else
  45. {
  46. return s;
  47. }
  48. }
  49. BOOL
  50. SxStressToolExtractFlagsFromString(
  51. PCFUSION_FLAG_FORMAT_MAP_ENTRY FlagData,
  52. ULONG NumberOfFlagData,
  53. PCWSTR FlagString,
  54. ULONG& FlagBits
  55. )
  56. {
  57. BOOL Success = FALSE;
  58. SxStressToolUnicodeString_t s(FlagString);
  59. SxStressToolUnicodeString_t delim(L" ,;\t+|"); // it'd be nice to support & and ~ ...
  60. std::vector<SxStressToolUnicodeString_t> v;
  61. //
  62. // first see if wcstoul could consume it all (this is a little sloppy)
  63. //
  64. if (FlagString[0] == '#')
  65. ++FlagString;
  66. if (wcsspn(FlagString, L" \tx-+0123456789") == wcslen(FlagString))
  67. {
  68. FlagBits |= wcstoul(FlagString, NULL, 0);
  69. Success = TRUE;
  70. goto Exit;
  71. }
  72. SxStressToolSplitString(s, delim, v);
  73. for (SIZE_T i = 0 ; i != v.size() ; ++i)
  74. {
  75. PCWSTR begin = v[i].begin();
  76. const PCWSTR end = v[i].end();
  77. SSIZE_T length = (end - begin);
  78. if (begin[0] == '#')
  79. {
  80. ++begin;
  81. --length;
  82. }
  83. if (StringSpan(begin, end, L" \tx-+0123456789") == length)
  84. {
  85. FlagBits |= wcstoul(FlagString, NULL, 0);
  86. continue;
  87. }
  88. for (SIZE_T j = 0 ; j != NumberOfFlagData ; ++j)
  89. {
  90. if (FusionpCompareStrings(
  91. FlagData[j].m_pszString,
  92. FlagData[j].m_cchString,
  93. begin,
  94. length,
  95. true
  96. ) == 0)
  97. {
  98. FlagBits |= FlagData[j].m_dwFlagMask;
  99. break;
  100. }
  101. if (FusionpCompareStrings(
  102. FlagData[j].m_pszShortString,
  103. FlagData[j].m_cchShortString,
  104. begin,
  105. length,
  106. true
  107. ) == 0)
  108. {
  109. FlagBits |= FlagData[j].m_dwFlagMask;
  110. break;
  111. }
  112. }
  113. }
  114. Success = TRUE;
  115. Exit:
  116. return Success;
  117. }
  118. BOOL
  119. pSxStressToolGetStringSetting(
  120. ULONG FutureFlags,
  121. PCWSTR IniFilePath,
  122. PCWSTR Section,
  123. PCWSTR Key,
  124. PCWSTR Default,
  125. PWSTR DumbBuffer,
  126. SIZE_T DumbBufferSize
  127. )
  128. {
  129. BOOL Success = FALSE;
  130. SIZE_T dwTemp = ::GetPrivateProfileStringW(Section, Key, Default, DumbBuffer, static_cast<ULONG>(DumbBufferSize), IniFilePath);
  131. if (dwTemp == (DumbBufferSize - 1))
  132. {
  133. ::FusionpSetLastWin32Error(ERROR_INVALID_PARAMETER);
  134. ::ReportFailure("Too large setting in \"%ls\"; section \"%ls\", key \"%ls\" (does not fit in %Iu characters).\n",
  135. IniFilePath, Section, Key, DumbBufferSize);
  136. goto Exit;
  137. }
  138. Success = TRUE;
  139. Exit:
  140. return Success;
  141. }
  142. BOOL
  143. SxStressToolGetStringSetting(
  144. ULONG FutureFlags,
  145. PCWSTR IniFilePath,
  146. PCWSTR Section,
  147. PCWSTR Key,
  148. PCWSTR Default,
  149. CBaseStringBuffer& Buffer,
  150. PCWSTR* DumbPointer
  151. )
  152. {
  153. BOOL Success = FALSE;
  154. WCHAR DumbBuffer[MAX_PATH];
  155. if (DumbPointer != NULL)
  156. *DumbPointer = NULL;
  157. if (!pSxStressToolGetStringSetting(0, IniFilePath, Section, Key, Default, DumbBuffer, NUMBER_OF(DumbBuffer)))
  158. goto Exit;
  159. if (!Buffer.Win32Append(DumbBuffer, ::wcslen(DumbBuffer)))
  160. goto Exit;
  161. if (DumbPointer != NULL)
  162. *DumbPointer = Buffer;
  163. Success = TRUE;
  164. Exit:
  165. return Success;
  166. }
  167. BOOL
  168. SxStressToolGetFlagSetting(
  169. ULONG FutureFlags,
  170. PCWSTR IniFilePath,
  171. PCWSTR Section,
  172. PCWSTR Key,
  173. ULONG& Flags,
  174. PCFUSION_FLAG_FORMAT_MAP_ENTRY FlagData,
  175. ULONG NumberOfFlagData
  176. )
  177. {
  178. BOOL Success = FALSE;
  179. WCHAR DumbBuffer[MAX_PATH];
  180. if (!pSxStressToolGetStringSetting(0, IniFilePath, Section, Key, L"", DumbBuffer, NUMBER_OF(DumbBuffer)))
  181. goto Exit;
  182. if (DumbBuffer[0] != 0)
  183. {
  184. if (!SxStressToolExtractFlagsFromString(FlagData, NumberOfFlagData, DumbBuffer, Flags))
  185. goto Exit;
  186. }
  187. Success = TRUE;
  188. Exit:
  189. return Success;
  190. }
  191. BOOL
  192. SxStressToolGetResourceIdSetting(
  193. ULONG FutureFlags,
  194. PCWSTR IniFilePath,
  195. PCWSTR Section,
  196. PCWSTR Key,
  197. CBaseStringBuffer& Buffer,
  198. PCWSTR* DumbPointer
  199. )
  200. {
  201. BOOL Success = FALSE;
  202. WCHAR DumbBuffer[MAX_PATH];
  203. *DumbPointer = NULL;
  204. if (!pSxStressToolGetStringSetting(0, IniFilePath, Section, Key, L"", DumbBuffer, NUMBER_OF(DumbBuffer)))
  205. goto Exit;
  206. if (DumbBuffer[0] != 0)
  207. {
  208. if (!Buffer.Win32Append(DumbBuffer, ::wcslen(DumbBuffer)))
  209. goto Exit;
  210. *DumbPointer = StringToResourceString(DumbBuffer);
  211. }
  212. Success = TRUE;
  213. Exit:
  214. return Success;
  215. }
  216. BOOL
  217. SxspIsPrivateProfileStringEqual(
  218. PCWSTR pcwszSection,
  219. PCWSTR pcwszKeyName,
  220. PCWSTR pcwszTestValue,
  221. BOOL &rfIsEqual,
  222. PCWSTR pcwszFileName
  223. )
  224. {
  225. FN_PROLOG_WIN32
  226. CSmallStringBuffer buffTemp;
  227. CSmallStringBuffer buffFakeDefault;
  228. rfIsEqual = FALSE;
  229. IFW32FALSE_EXIT(buffFakeDefault.Win32Assign(pcwszTestValue, ::wcslen(pcwszTestValue)));
  230. IFW32FALSE_EXIT(buffFakeDefault.Win32AppendPathElement(L"2", 1));
  231. IFW32FALSE_EXIT(SxspGetPrivateProfileStringW(
  232. pcwszSection,
  233. pcwszKeyName,
  234. buffFakeDefault,
  235. buffTemp,
  236. pcwszFileName));
  237. //
  238. // Did we get back something other than the "fake" default?
  239. //
  240. if (FusionpCompareStrings(buffTemp, buffFakeDefault, TRUE) != 0)
  241. rfIsEqual = (FusionpStrCmpI(buffTemp, pcwszTestValue) == 0);
  242. FN_EPILOG
  243. }
  244. BOOL
  245. SxspGetPrivateProfileStringW(
  246. PCWSTR pcwszSection,
  247. PCWSTR pcwszKeyName,
  248. PCWSTR pcwszDefault,
  249. OUT CBaseStringBuffer &buffTarget,
  250. PCWSTR pcwszFileName)
  251. {
  252. FN_PROLOG_WIN32
  253. buffTarget.Clear();
  254. do
  255. {
  256. CStringBufferAccessor sba(&buffTarget);
  257. const DWORD dwNeededSize = ::GetPrivateProfileStringW(
  258. pcwszSection,
  259. pcwszKeyName,
  260. pcwszDefault,
  261. sba.GetBufferPtr(),
  262. sba.GetBufferCchAsINT(),
  263. pcwszFileName);
  264. if ( dwNeededSize == 0 )
  265. {
  266. if ( ::FusionpGetLastWin32Error() != ERROR_SUCCESS )
  267. ORIGINATE_WIN32_FAILURE_AND_EXIT(GetPrivateProfileStringW, ::FusionpGetLastWin32Error());
  268. else
  269. break;
  270. }
  271. else if ( dwNeededSize < sba.GetBufferCch() )
  272. {
  273. break;
  274. }
  275. else
  276. {
  277. sba.Detach();
  278. IFW32FALSE_EXIT(buffTarget.Win32ResizeBuffer( dwNeededSize + 1, eDoNotPreserveBufferContents));
  279. }
  280. }
  281. while ( true );
  282. FN_EPILOG
  283. }
  284. BOOL
  285. SxspGetPrivateProfileIntW(
  286. PCWSTR pcwszSection,
  287. PCWSTR pcwszKeyName,
  288. INT defaultValue,
  289. INT &Target,
  290. PCWSTR pcwszFilename)
  291. {
  292. FN_PROLOG_WIN32
  293. Target = GetPrivateProfileIntW(pcwszSection, pcwszKeyName, defaultValue, pcwszFilename);
  294. FN_EPILOG
  295. }