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.

416 lines
11 KiB

  1. //-------------------------------------------------------------------------
  2. //
  3. // Microsoft OLE
  4. // Copyright (C) Microsoft Corporation, 1995 - 1997.
  5. //
  6. // File: dbcs.cxx
  7. //
  8. // Contents: Contains DBCS string generator
  9. //
  10. // History: 03-Nov-97 BogdanT Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <dfheader.hxx>
  14. #include <dbcs.hxx>
  15. DH_DECLARE;
  16. //---------------------------------------------------------------------------
  17. //
  18. // Method: CDBCSStringGen::CDBCSStringGen
  19. //
  20. // Synopsis: Constructor
  21. //
  22. // Parameters: none
  23. //
  24. // History: 03-Nov-97 BogdanT Created
  25. //
  26. //---------------------------------------------------------------------------
  27. CDBCSStringGen::CDBCSStringGen()
  28. {
  29. #ifdef _MAC
  30. m_uCodePage = 1252;
  31. #else
  32. m_uCodePage = GetACP();
  33. #endif
  34. m_fSystemIsDBCS = TRUE;
  35. m_hDataFile = NULL;
  36. m_ptszDataFile = NULL;
  37. m_cFileNames = 0;
  38. m_pdgi = NULL;
  39. }
  40. //---------------------------------------------------------------------------
  41. //
  42. // Method: CDBCSStringGen::~CDBCSStringGen
  43. //
  44. // Synopsis: Destructor
  45. //
  46. // Parameters:
  47. //
  48. // History: 03-Nov-97 BogdanT Created
  49. //
  50. //---------------------------------------------------------------------------
  51. CDBCSStringGen::~CDBCSStringGen()
  52. {
  53. delete[] m_ptszDataFile;
  54. delete m_pdgi;
  55. if(NULL != m_hDataFile)
  56. {
  57. fclose(m_hDataFile);
  58. }
  59. }
  60. //---------------------------------------------------------------------------
  61. //
  62. // Method: CDBCSStringGen::Init
  63. //
  64. // Synopsis: Initialize the object
  65. //
  66. // Parameters: [dwSeed] -- used to seed the internal DG object
  67. //
  68. // History: 03-Nov-97 BogdanT Created
  69. //
  70. //---------------------------------------------------------------------------
  71. HRESULT CDBCSStringGen::Init(DWORD dwSeed)
  72. {
  73. HRESULT hr = S_OK;
  74. DH_FUNCENTRY(&hr, DH_LVL_TRACE1, TEXT("CDBCSStringGen::Init"));
  75. _tsetlocale(LC_ALL, TEXT("")); // set locale for RTL routine;
  76. // if we don't, console output won't work
  77. // with DBCS strings
  78. if(S_OK == hr)
  79. {
  80. m_pdgi = new DG_INTEGER(dwSeed);
  81. if(NULL == m_pdgi)
  82. {
  83. hr = E_OUTOFMEMORY;
  84. DH_HRCHECK(hr, TEXT("new DG_INTEGER"));
  85. }
  86. }
  87. if(S_OK == hr)
  88. {
  89. m_ptszDataFile = new TCHAR[_MAX_FNAME];
  90. if(NULL == m_ptszDataFile)
  91. {
  92. hr = E_OUTOFMEMORY;
  93. DH_HRCHECK(hr, TEXT("new TCHAR"));
  94. }
  95. }
  96. // check if system is DBCS and set the data file accordingly
  97. m_fSystemIsDBCS = TRUE;
  98. switch(m_uCodePage)
  99. {
  100. case CP_JPN: _tcscpy(m_ptszDataFile, NAMEFILE_JPN);
  101. DH_TRACE((DH_LVL_TRACE1, TEXT("DBCS Japan - ACP %d"), m_uCodePage));
  102. break;
  103. case CP_CHS: _tcscpy(m_ptszDataFile, NAMEFILE_CHS);
  104. DH_TRACE((DH_LVL_TRACE1, TEXT("DBCS China - ACP %d"), m_uCodePage));
  105. break;
  106. case CP_KOR: _tcscpy(m_ptszDataFile, NAMEFILE_KOR);
  107. DH_TRACE((DH_LVL_TRACE1, TEXT("DBCS Korea - ACP %d"), m_uCodePage));
  108. break;
  109. case CP_CHT: _tcscpy(m_ptszDataFile, NAMEFILE_CHT);
  110. DH_TRACE((DH_LVL_TRACE1, TEXT("DBCS Taiwan/Hong Kong - ACP %d"), m_uCodePage));
  111. break;
  112. default: _tcscpy(m_ptszDataFile, TEXT(""));
  113. DH_TRACE((DH_LVL_DFLIB, TEXT("SBCS - ACP %d"), m_uCodePage));
  114. m_fSystemIsDBCS = FALSE;
  115. break;
  116. }
  117. if(S_OK == hr)
  118. {
  119. if(m_fSystemIsDBCS)
  120. {
  121. DH_ASSERT(NULL!=m_ptszDataFile);
  122. m_hDataFile = _tfopen(m_ptszDataFile, TEXT("r"));
  123. if(NULL == m_hDataFile)
  124. {
  125. hr = HRESULT_FROM_WIN32(GetLastError());
  126. DH_HRCHECK(hr, TEXT("_tfopen"));
  127. }
  128. if(S_OK == hr)
  129. {
  130. m_cFileNames = CountNamesInFile();
  131. }
  132. }
  133. }
  134. return hr;
  135. }
  136. //---------------------------------------------------------------------------
  137. //
  138. // Method: CDBCSStringGen::CountNamesInFile
  139. //
  140. // Synopsis: Count number of filenames in data file
  141. //
  142. // Parameters: none
  143. //
  144. // History: 03-Nov-97 BogdanT Created
  145. //
  146. //---------------------------------------------------------------------------
  147. UINT CDBCSStringGen::CountNamesInFile()
  148. {
  149. UINT cNames = 0;
  150. TCHAR lptszCrtLine[MAX_LINE_SIZE];
  151. if(FALSE == m_fSystemIsDBCS) // there is no data file if system is not DBCS
  152. {
  153. return 0;
  154. }
  155. DH_ASSERT(NULL != m_hDataFile);
  156. fseek(m_hDataFile, SEEK_SET, 0);
  157. // count all valid lines in the file
  158. while(_fgetts(lptszCrtLine, MAX_LINE_SIZE-1, m_hDataFile))
  159. {
  160. // we assume every line containing a filename starts with
  161. // a hex character
  162. // e.g. fc4b,8140,fc4b,2e,54,78,54
  163. if(_istxdigit(lptszCrtLine[0]))
  164. {
  165. cNames++;
  166. }
  167. }
  168. fseek(m_hDataFile, SEEK_SET, 0);
  169. return cNames;
  170. }
  171. //---------------------------------------------------------------------------
  172. //
  173. // Method: CDBCSStringGen::GenerateRandomFileName
  174. //
  175. // Synopsis: Generate a random filename from the current data file
  176. //
  177. // Parameters: [pptszName] -- pointer to receive the generated name
  178. //
  179. // History: 03-Nov-97 BogdanT Created
  180. //
  181. // Comments: This function allocates space for the filename; the caller
  182. // is responsible for freeing the memory
  183. //
  184. //---------------------------------------------------------------------------
  185. HRESULT CDBCSStringGen::GenerateRandomFileName(LPTSTR *pptszName)
  186. {
  187. HRESULT hr = S_OK;
  188. UINT uNameIndex = 0xffff;
  189. LPSTR lpHex = NULL;
  190. LPSTR lpName = NULL;
  191. INT nStringLen = 0;
  192. LPTSTR ptszDest = NULL;
  193. CHAR szNameInHex[MAX_LINE_SIZE];
  194. CHAR szDBCSName[_MAX_FNAME];
  195. DH_FUNCENTRY(&hr, DH_LVL_TRACE1, TEXT("CDBCSStringGen::GenerateRandomFileName"));
  196. DH_VDATEPTROUT(pptszName, LPTSTR*);
  197. if(0 == m_cFileNames)
  198. {
  199. return S_FALSE;
  200. }
  201. DH_ASSERT(NULL != m_pdgi);
  202. m_pdgi->Generate(&uNameIndex, 0, m_cFileNames-1);
  203. hr = GetFileNameFromFile(uNameIndex, szNameInHex);
  204. DH_HRCHECK(hr, TEXT("GetFileNameFromFile"));
  205. if(S_OK == hr)
  206. {
  207. // now convert ascii hex string
  208. // the strings look like this: fc4b,8140,fc4b,2e,54,78,54
  209. for(lpHex=szNameInHex, lpName = szDBCSName; *lpHex!='\0'; lpName++)
  210. {
  211. while(!isxdigit(*lpHex) && *lpHex!='\0')
  212. {
  213. lpHex++;
  214. }
  215. // bail if we reach the end
  216. if(*lpHex == '\0')
  217. break;
  218. *lpName = (CHAR)(16*Hex(*lpHex++));
  219. //
  220. // the only assumption we make is that the two hex digits that
  221. // represent each byte are not separated;
  222. //
  223. // you will get an assert in the next line if the file contains
  224. // something like "1f,4 b"
  225. // ^-non hex digit here
  226. //
  227. DH_ASSERT(isxdigit(*lpHex));
  228. *lpName = (CHAR)(*lpName + (Hex(*lpHex++)));
  229. }
  230. *lpName = '\0';
  231. }
  232. #ifdef UNICODE
  233. if(S_OK == hr)
  234. {
  235. // get the needed buffer size
  236. nStringLen = MultiByteToWideChar(
  237. CP_ACP,
  238. 0,
  239. szDBCSName,
  240. -1,
  241. NULL,
  242. 0) ;
  243. if(0 == nStringLen)
  244. {
  245. hr = HRESULT_FROM_WIN32(GetLastError());
  246. DH_HRCHECK(hr, TEXT("MultiByteToWideChar"));
  247. }
  248. }
  249. if(S_OK == hr)
  250. {
  251. ptszDest = new WCHAR[nStringLen];
  252. if(NULL == ptszDest)
  253. {
  254. hr = E_OUTOFMEMORY;
  255. DH_HRCHECK(hr, TEXT("new WCHAR"));
  256. }
  257. }
  258. if(S_OK == hr)
  259. {
  260. if (nStringLen != MultiByteToWideChar(
  261. CP_ACP,
  262. 0,
  263. szDBCSName,
  264. -1,
  265. ptszDest,
  266. nStringLen))
  267. {
  268. hr = HRESULT_FROM_WIN32(GetLastError());
  269. DH_HRCHECK(hr, TEXT("MultiByteToWideChar"));
  270. }
  271. }
  272. if(S_OK == hr)
  273. {
  274. *pptszName = ptszDest;
  275. }
  276. #else
  277. if(S_OK == hr)
  278. {
  279. nStringLen = strlen(szDBCSName);
  280. ptszDest = new CHAR[nStringLen+1];
  281. if(NULL == ptszDest)
  282. {
  283. hr = E_OUTOFMEMORY;
  284. DH_HRCHECK(hr, TEXT("new WCHAR"));
  285. }
  286. }
  287. if(S_OK == hr)
  288. {
  289. strcpy(ptszDest, szDBCSName);
  290. }
  291. #endif //UNICODE
  292. if(S_OK == hr)
  293. {
  294. *pptszName = ptszDest;
  295. }
  296. DH_TRACE((DH_LVL_TRACE2, TEXT("GenerateRandomFileName: %s"),
  297. (S_OK == hr)?*pptszName:TEXT("none")));
  298. return hr;
  299. }
  300. //---------------------------------------------------------------------------
  301. //
  302. // Method: CDBCSStringGen::GetFileNameFromFile
  303. //
  304. // Synopsis: Get a specific name from data file
  305. //
  306. // Parameters: [nIndex] -- name to be retrieved
  307. // [lpDest] -- buffer to receive the string; must be big large
  308. // enough
  309. //
  310. // History: 03-Nov-97 BogdanT Created
  311. //
  312. //
  313. //---------------------------------------------------------------------------
  314. HRESULT CDBCSStringGen::GetFileNameFromFile(UINT nIndex, LPSTR lpDest)
  315. {
  316. HRESULT hr = S_OK;
  317. UINT nCount = 0;
  318. CHAR szBuf[MAX_LINE_SIZE];
  319. DH_FUNCENTRY(&hr, DH_LVL_TRACE1, TEXT("CDBCSStringGen::GetFileNameFromFile"));
  320. DH_ASSERT(NULL != m_hDataFile);
  321. fseek(m_hDataFile, SEEK_SET, 0);
  322. DH_ASSERT(nIndex<m_cFileNames);
  323. do
  324. {
  325. if(!fgets(szBuf, MAX_LINE_SIZE-1, m_hDataFile))
  326. {
  327. hr = E_FAIL;
  328. DH_HRCHECK(hr, TEXT("fgets"));
  329. break;
  330. }
  331. if(isxdigit(szBuf[0])) // ignore comments and other invalid lines
  332. { // the strings look like this: fc4b,8140,fc4b,2e,54
  333. nCount++;
  334. }
  335. }while(nCount<=nIndex);
  336. fseek(m_hDataFile, SEEK_SET, 0);
  337. if(S_OK == hr)
  338. {
  339. strcpy(lpDest, szBuf);
  340. }
  341. return hr;
  342. }