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.

3664 lines
105 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1998.
  5. //
  6. // File: util.cpp
  7. //
  8. // Contents: Miscellaneous utility functions
  9. //
  10. // History:
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "stdafx.h"
  14. #include "util.h"
  15. #include "wrapper.h"
  16. #include "defvals.h"
  17. #include "resource.h"
  18. #include <io.h>
  19. #include "snapmgr.h"
  20. extern "C" {
  21. #include "getuser.h"
  22. }
  23. #define ILLEGAL_FILENAME_CHARS L"\"+,;<=>"
  24. #define ILLEGAL_FILENAME_CHARS1 L"\\\\ \\/ // /\\"
  25. #define ILLEGAL_FILENAME_CHARS2 L"\\ /"
  26. //////////////////////////////////////////////////////////////////////////////////////////
  27. // CWriteHmtlFile body.
  28. //
  29. //+-------------------------------------------------------------------------------------------
  30. // CWriteHtmlFile::CWriteHtmlFile
  31. //
  32. // Initialize the class.
  33. //
  34. //--------------------------------------------------------------------------------------------
  35. CWriteHtmlFile::CWriteHtmlFile()
  36. {
  37. m_hFileHandle = INVALID_HANDLE_VALUE;
  38. m_bErrored = FALSE;
  39. }
  40. //+-------------------------------------------------------------------------------------------
  41. // CWriteHtmlFile::~CWriteHtmlFile
  42. //
  43. // Write the end of the html file and close the handle.
  44. //
  45. //--------------------------------------------------------------------------------------------
  46. CWriteHtmlFile::~CWriteHtmlFile()
  47. {
  48. //
  49. // Close the file handle, but don't delete the HTML file, unless there was an
  50. // error during some write proccess.
  51. //
  52. Close(m_bErrored);
  53. }
  54. //+-------------------------------------------------------------------------------------------
  55. // CWriteHtmlFile::Close
  56. //
  57. // Closes the HTML file handle, if [bDelete] is true then the file is deleted.
  58. //
  59. // Arguments: [bDelete] - Close and delete the file.
  60. //
  61. // Returns: ERROR_SUCCESS;
  62. //--------------------------------------------------------------------------------------------
  63. DWORD
  64. CWriteHtmlFile::Close( BOOL bDelete )
  65. {
  66. if(m_hFileHandle == INVALID_HANDLE_VALUE){
  67. return ERROR_SUCCESS;
  68. }
  69. if(bDelete){
  70. CloseHandle(m_hFileHandle);
  71. DeleteFile(m_strFileName );
  72. } else {
  73. Write( IDS_HTMLERR_END );
  74. CloseHandle( m_hFileHandle );
  75. }
  76. m_hFileHandle = INVALID_HANDLE_VALUE;
  77. return ERROR_SUCCESS;
  78. }
  79. //+-------------------------------------------------------------------------------------------
  80. // CWriteHtmlFile::GetFileName
  81. //
  82. // Copies the file name associated with this class to [pstrFileName].
  83. //
  84. // Arguments: [pstrFileName] - A CString object which will contain the file name
  85. // on return.
  86. //
  87. // Returns: 0 - If Create has not been called, or the HTML file is invalid for
  88. // some reason. This could be caused by a bad write.
  89. // The size in characters of the file name.
  90. //
  91. //--------------------------------------------------------------------------------------------
  92. int CWriteHtmlFile::GetFileName( LPTSTR pszFileName, UINT nSize )
  93. {
  94. if(m_strFileName.IsEmpty() || m_hFileHandle == INVALID_HANDLE_VALUE || m_bErrored){
  95. return 0;
  96. }
  97. if(pszFileName && (int)nSize > m_strFileName.GetLength()){
  98. //This is a safe usage.
  99. lstrcpy(pszFileName, m_strFileName);
  100. }
  101. return m_strFileName.GetLength();
  102. }
  103. //+-------------------------------------------------------------------------------------------
  104. // CWriteHtmlFile::Write
  105. //
  106. // Writes a string resource to the html file at the current file position.
  107. //
  108. // Arguments: [uRes] - The String resource to load and write to the html.
  109. //
  110. // Returns: If the string can't be loaded then an error will be returned.
  111. // See CWriteHtmlFile::Write( LPCTSTR ) for other errors.
  112. //--------------------------------------------------------------------------------------------
  113. DWORD
  114. CWriteHtmlFile::Write( UINT uRes )
  115. {
  116. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  117. CString str;
  118. if( !str.LoadString(uRes) ){
  119. return GetLastError();
  120. }
  121. #if defined(UNICODE) || defined(_UNICODE)
  122. if ( uRes == IDS_HTMLERR_HEADER ){
  123. WCHAR wszByteOrderMark[2] = {0xFEFF, 0x0000};
  124. CString strByteOrderMark = wszByteOrderMark;
  125. return Write( strByteOrderMark + str );
  126. } else
  127. #endif
  128. return Write( str );
  129. }
  130. //+-------------------------------------------------------------------------------------------
  131. // CWriteHtmlFile::Write
  132. //
  133. // Writes a string to an html file.
  134. //
  135. // Arguments: [pszString] - The string to write.
  136. //
  137. // Returns: ERROR_NOT_READ - if Create has not been called, or the file could not
  138. // not be created.
  139. // Other errors returned by WriteFile();
  140. //--------------------------------------------------------------------------------------------
  141. DWORD
  142. CWriteHtmlFile::Write(LPCTSTR pszString, ... )
  143. {
  144. if(m_hFileHandle == INVALID_HANDLE_VALUE)
  145. {
  146. return ERROR_NOT_READY;
  147. }
  148. CString szWrite;
  149. va_list marker;
  150. va_start(marker, pszString);
  151. //This is not a safe usage. Avoid using vswprintf(). Raid #555867. Yanggao.
  152. szWrite.FormatV(pszString, marker);
  153. va_end(marker);
  154. DWORD dwRight;
  155. if( !WriteFile( m_hFileHandle, szWrite, sizeof(TCHAR) * szWrite.GetLength(), &dwRight, NULL) )
  156. {
  157. //
  158. // Check the error state of the right. Set m_bErrored if there was something wrong
  159. // with the write.
  160. //
  161. dwRight = GetLastError();
  162. if(dwRight != ERROR_SUCCESS)
  163. {
  164. m_bErrored = TRUE;
  165. }
  166. }
  167. else
  168. {
  169. dwRight = ERROR_SUCCESS;
  170. }
  171. return dwRight;
  172. }
  173. DWORD
  174. CWriteHtmlFile::CopyTextFile(
  175. LPCTSTR pszFile,
  176. DWORD dwPosLow,
  177. BOOL bInterpret
  178. )
  179. {
  180. HANDLE handle;
  181. //
  182. // Try to open the file for reading.
  183. //
  184. handle = ExpandAndCreateFile( pszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );
  185. if(handle == INVALID_HANDLE_VALUE)
  186. {
  187. return GetLastError();
  188. }
  189. LONG dwPosHigh = 0;
  190. WCHAR szText[256];
  191. char szRead[256];
  192. BOOL IsMulti;
  193. DWORD isUnicode;
  194. //
  195. // Determine if the file is a unicode text file.
  196. //
  197. if( ReadFile(handle, szText, 100 * sizeof(WCHAR), (DWORD *)&dwPosHigh, NULL ) == 0 ) //Raid #prefast
  198. {
  199. CloseHandle(handle );
  200. return GetLastError();
  201. }
  202. if(dwPosHigh )
  203. {
  204. isUnicode = IsTextUnicode( szText, dwPosHigh, NULL );
  205. }
  206. //
  207. // Set the pos we want to start from
  208. //
  209. dwPosHigh = 0;
  210. SetFilePointer( handle, dwPosLow, &dwPosHigh, FILE_BEGIN );
  211. if( GetLastError() != ERROR_SUCCESS )
  212. {
  213. CloseHandle(handle );
  214. return GetLastError();
  215. }
  216. DWORD dwErr = ERROR_SUCCESS;
  217. do
  218. {
  219. start:
  220. //
  221. // Read 254 total bytes from the file. We don't care about the error returned
  222. // by read, as long as read does not set dwPosHigh to something.
  223. //
  224. dwPosHigh = 0;
  225. if( ReadFile( handle, szRead, 254, (DWORD *)&dwPosHigh, NULL ) == 0 || dwPosHigh == 0) //Raid #prefast
  226. {
  227. CloseHandle(handle );
  228. return GetLastError();
  229. }
  230. //
  231. // If the file is not considered unicode then convert it to a unicode file.
  232. //
  233. ZeroMemory(szText, sizeof(WCHAR) * 256);
  234. if(!isUnicode)
  235. {
  236. //This is a safe usage.
  237. dwPosHigh = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szRead, dwPosHigh, szText, 255 );
  238. }
  239. else
  240. {
  241. //
  242. // Just copy the text to the szText buffer and get the number of UNICODE
  243. // characters.
  244. //
  245. //This is a safe usage.
  246. memcpy(szText, szRead, dwPosHigh);
  247. dwPosHigh = wcslen(szText);
  248. }
  249. PWSTR pszWrite = szText;
  250. LONG i = 0;
  251. if( bInterpret )
  252. {
  253. //
  254. // Write out line breaks.
  255. //
  256. for(;i < dwPosHigh; i++)
  257. {
  258. //Bug 141526, Yanggao, 3/20/2001
  259. if( L'<' == szText[i] )
  260. {
  261. szText[i] = 0;
  262. Write(pszWrite);
  263. Write(L"&lt");
  264. pszWrite = &(szText[i + 1]);
  265. }
  266. if( L'%' == szText[i] ) //Raid #624384,Yanggao
  267. {
  268. szText[i] = 0;
  269. Write(pszWrite);
  270. Write(L"%%");
  271. pszWrite = &(szText[i + 1]);
  272. }
  273. if( L'\r' == szText[i] || L'\n' == szText[i] )
  274. {
  275. if( i + 1 >= dwPosHigh )
  276. {
  277. szText[i] = 0;
  278. Write(pszWrite);
  279. SetFilePointer( handle, -(isUnicode ? 2:1), NULL, FILE_CURRENT);
  280. //
  281. // Read once again.
  282. //
  283. goto start;
  284. }
  285. //
  286. // Check to see if this is a valid line break
  287. //
  288. i++;
  289. if( L'\r' == szText[i] || L'\n' == szText[i] &&
  290. szText[i] != szText[i - 1] )
  291. {
  292. szText[i - 1] = 0;
  293. dwErr = Write( pszWrite );
  294. if( dwErr != ERROR_SUCCESS)
  295. {
  296. break;
  297. }
  298. dwErr = Write( L"<BR>" );
  299. if( dwErr != ERROR_SUCCESS)
  300. {
  301. break;
  302. }
  303. pszWrite = &(szText[i + 1]);
  304. }
  305. else
  306. {
  307. //
  308. // This is not a valid line break, contintue with check with next character
  309. //
  310. i--;
  311. }
  312. }
  313. }
  314. }
  315. //
  316. // Write the rest of the text.
  317. //
  318. if(dwErr == ERROR_SUCCESS)
  319. {
  320. Write( pszWrite );
  321. }
  322. else
  323. {
  324. break;
  325. }
  326. } while( dwPosHigh );
  327. CloseHandle(handle );
  328. return ERROR_SUCCESS;
  329. }
  330. //+-------------------------------------------------------------------------------------------
  331. // CWriteHtmlFile::Create
  332. //
  333. // Creates an html file, and starts the write proccess. If [pszFile] is null, then
  334. // this function creates a temporary file in the GetTempPath() directory with a name
  335. // like SCE###.HTM
  336. //
  337. // Arguments: [pszFile] - Optional parameter for file name
  338. //
  339. // returns: ERROR_SUCCESS - If creating the file was successful.
  340. // If the file exists then ERROR_FILE_EXISTS is returned.
  341. //
  342. //--------------------------------------------------------------------------------------------
  343. DWORD CWriteHtmlFile::Create(LPCTSTR pszFile )
  344. {
  345. if(!pszFile){
  346. //
  347. // Create a temporary file name.
  348. //
  349. DWORD dwSize = GetTempPath(0, NULL);
  350. if(dwSize){
  351. TCHAR szTempFile[512];
  352. //
  353. // Get the temp path.
  354. //
  355. LPTSTR pszPath = (LPTSTR)LocalAlloc( 0, (dwSize + 1) * sizeof(TCHAR));
  356. if(!pszPath){
  357. return ERROR_OUTOFMEMORY;
  358. }
  359. GetTempPath( dwSize + 1, pszPath );
  360. pszPath[dwSize - 1] = 0;
  361. if( GetTempFileName( pszPath, TEXT("SCE"), 0, szTempFile) ){ //This is not safe usage. Raid #555912, yanggao.
  362. LocalFree(pszPath);
  363. //
  364. // Create the temporary file.
  365. //
  366. DeleteFile( szTempFile );
  367. int i = lstrlen(szTempFile);
  368. while(i--){
  369. if( szTempFile[i] == L'.' ){
  370. break;
  371. }
  372. }
  373. if(i + 3 >= lstrlen(szTempFile)){
  374. return ERROR_OUTOFMEMORY;
  375. }
  376. //
  377. // We want to create an html file.
  378. //
  379. i++;
  380. szTempFile[i] = L'h';
  381. szTempFile[i + 1] = L't';
  382. szTempFile[i + 2] = L'm';
  383. m_strFileName = szTempFile;
  384. } else {
  385. LocalFree(pszPath);
  386. }
  387. }
  388. } else {
  389. m_strFileName = pszFile;
  390. }
  391. if(m_strFileName.IsEmpty()){
  392. return ERROR_FILE_NOT_FOUND;
  393. }
  394. //
  395. // Open the file for writing
  396. //
  397. m_hFileHandle = ExpandAndCreateFile( m_strFileName,
  398. GENERIC_WRITE,
  399. FILE_SHARE_READ,
  400. NULL,
  401. CREATE_ALWAYS,
  402. FILE_ATTRIBUTE_TEMPORARY,
  403. NULL
  404. );
  405. if(m_hFileHandle == INVALID_HANDLE_VALUE){
  406. return GetLastError();
  407. }
  408. //
  409. // Write HTML header
  410. //
  411. return Write( IDS_HTMLERR_HEADER );
  412. }
  413. //+--------------------------------------------------------------------------
  414. //
  415. // Function: MyRegQueryValue
  416. //
  417. // Synopsis: Reads a registry value into [*Value]
  418. //
  419. //
  420. // Arguments: [hKeyRoot] -
  421. // [SubKey] -
  422. // [ValueName] -
  423. // [Value] -
  424. // [pRegType] -
  425. //
  426. // Modifies: *[Value]
  427. // *[pRegType]
  428. //
  429. // History:
  430. //
  431. //---------------------------------------------------------------------------
  432. DWORD MyRegQueryValue( HKEY hKeyRoot,
  433. LPCTSTR SubKey,
  434. LPCTSTR ValueName,
  435. PVOID *Value,
  436. LPDWORD pRegType )
  437. {
  438. DWORD Rcode;
  439. DWORD dSize=0;
  440. HKEY hKey=NULL;
  441. BOOL FreeMem=FALSE;
  442. if (( Rcode = RegOpenKeyEx(hKeyRoot, SubKey, 0,
  443. KEY_READ, &hKey )) == ERROR_SUCCESS ) {
  444. //This is a safe usage. It only queries data type.
  445. if (( Rcode = RegQueryValueEx(hKey, ValueName, 0,
  446. pRegType, NULL,
  447. &dSize )) == ERROR_SUCCESS ) {
  448. switch (*pRegType) {
  449. case REG_DWORD:
  450. case REG_DWORD_BIG_ENDIAN:
  451. //This is a safe usage. The data type is not REG_SZ.
  452. Rcode = RegQueryValueEx(hKey, ValueName, 0,
  453. pRegType, (BYTE *)(*Value),
  454. &dSize );
  455. if ( Rcode != ERROR_SUCCESS ) {
  456. if ( *Value != NULL )
  457. *((BYTE *)(*Value)) = 0;
  458. }
  459. break;
  460. case REG_SZ:
  461. case REG_EXPAND_SZ:
  462. case REG_MULTI_SZ:
  463. if ( *Value == NULL ) {
  464. *Value = (PVOID)LocalAlloc( LPTR, (dSize+1)*sizeof(TCHAR));
  465. FreeMem = TRUE;
  466. }
  467. if ( *Value == NULL ) {
  468. Rcode = ERROR_NOT_ENOUGH_MEMORY;
  469. } else {
  470. //This is not a safe usage. make sure *Value is terminated. Raid #555873. yanggao.
  471. Rcode = RegQueryValueEx(hKey,ValueName,0,
  472. pRegType,(BYTE *)(*Value),
  473. &dSize );
  474. if ( (Rcode != ERROR_SUCCESS) && FreeMem ) {
  475. LocalFree(*Value);
  476. *Value = NULL;
  477. }
  478. }
  479. break;
  480. default:
  481. Rcode = ERROR_INVALID_DATATYPE;
  482. break;
  483. }
  484. }
  485. }
  486. if ( hKey ) {
  487. RegCloseKey( hKey );
  488. }
  489. return(Rcode);
  490. }
  491. //+--------------------------------------------------------------------------
  492. //
  493. // Function: MyRegSetValue
  494. //
  495. // Synopsis: Writes a registry value into [*Value]
  496. //
  497. //
  498. // Arguments: [hKeyRoot] -
  499. // [SubKey] -
  500. // [ValueName] -
  501. // [Value] -
  502. // [cbValue] -
  503. // [pRegType] -
  504. //
  505. //
  506. // History:
  507. //
  508. //---------------------------------------------------------------------------
  509. DWORD MyRegSetValue( HKEY hKeyRoot,
  510. LPCTSTR SubKey,
  511. LPCTSTR ValueName,
  512. const BYTE *Value,
  513. const DWORD cbValue,
  514. const DWORD pRegType )
  515. {
  516. DWORD Rcode=0;
  517. HKEY hKey=NULL;
  518. BOOL FreeMem=FALSE;
  519. if (( Rcode = RegCreateKeyEx(hKeyRoot,
  520. SubKey,
  521. 0,
  522. 0,
  523. 0,
  524. KEY_READ|KEY_SET_VALUE|KEY_CREATE_SUB_KEY,
  525. NULL,
  526. &hKey,
  527. NULL)) == ERROR_SUCCESS ) {
  528. Rcode = RegSetValueEx(hKey,
  529. ValueName,
  530. 0,
  531. pRegType,
  532. Value,
  533. cbValue );
  534. }
  535. if ( hKey ) {
  536. RegCloseKey( hKey );
  537. }
  538. return(Rcode);
  539. }
  540. BOOL FilePathExist(LPCTSTR Name, BOOL IsPath, int Flag)
  541. // Flag = 0 - check file, Flag = 1 - check path
  542. {
  543. // TODO:
  544. struct _wfinddata_t FileInfo;
  545. intptr_t hFile;
  546. BOOL bExist = FALSE;
  547. if ( (IsPath && Flag == 1) ||
  548. (!IsPath && Flag == 0) ) {
  549. // must be exact match
  550. hFile = _wfindfirst((LPTSTR)Name, &FileInfo);
  551. if ( hFile != -1 ) {// find it
  552. if ( FileInfo.attrib & _A_SUBDIR ) {
  553. if ( Flag == 1)
  554. bExist = TRUE;
  555. } else if ( Flag == 0 )
  556. bExist = TRUE;
  557. }
  558. _findclose(hFile);
  559. return bExist;
  560. }
  561. if ( IsPath && Flag == 0 ) {
  562. // invalid parameter
  563. return bExist;
  564. }
  565. // IsPath = FALSE and Flag == 1 (a file name is passed in and search for its path)
  566. CString tmpstr = CString(Name);
  567. int nPos = tmpstr.ReverseFind(L'\\');
  568. if ( nPos > 2 ) {
  569. hFile = _wfindfirst(tmpstr.GetBufferSetLength(nPos), &FileInfo);
  570. if ( hFile != -1 && FileInfo.attrib & _A_SUBDIR )
  571. bExist = TRUE;
  572. _findclose(hFile);
  573. } else if ( nPos == 2 && Name[1] == L':')
  574. bExist = TRUE;
  575. return bExist;
  576. }
  577. //+--------------------------------------------------------------------------
  578. //
  579. // Function: MyFormatResMessage
  580. //
  581. // Synopsis: Creates an error message combining a description of an error
  582. // returned from an SCE function (in rc), the extended description
  583. // of that error (in errBuf), and a custom error message
  584. // (in residMessage)
  585. //
  586. // Arguments: [rc] - The return code of an SCE function
  587. // [residMessage] - the resource id of the base error message
  588. // [errBuf] - Extended error info returned from an SCE function
  589. // [strOut] - A CString to hold the formatted message
  590. //
  591. // Modifies: [strOut]
  592. //
  593. // History:
  594. //
  595. //---------------------------------------------------------------------------
  596. void
  597. MyFormatResMessage(SCESTATUS rc, // in
  598. UINT residMessage, // in
  599. PSCE_ERROR_LOG_INFO errBuf,// in, optional
  600. CString& strOut) // out
  601. {
  602. CString strMessage;
  603. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  604. //
  605. // If the LoadResource fails then strMessage will be empty
  606. // It'll still be better to format the rest of the message than
  607. // to return an empty strOut.
  608. //
  609. strMessage.LoadString(residMessage);
  610. MyFormatMessage(rc,strMessage,errBuf,strOut);
  611. }
  612. //+--------------------------------------------------------------------------
  613. //
  614. // Function: MyFormatMessage
  615. //
  616. // Synopsis: Creates an error message combining a description of an error
  617. // returned from an SCE function (in rc), the extended description
  618. // of that error (in errBuf), and a custom error message (in mes)
  619. //
  620. // Arguments: [rc] - The return code of an SCE function
  621. // [mes] - The base message
  622. // [errBuf] - Extended error info returned from an SCE function
  623. // [strOut] - A CString to hold the formatted message
  624. //
  625. // Modifies: [strOut]
  626. //
  627. // History:
  628. //
  629. //---------------------------------------------------------------------------
  630. void
  631. MyFormatMessage(SCESTATUS rc, // in
  632. LPCTSTR mes, // in
  633. PSCE_ERROR_LOG_INFO errBuf, // in, optional
  634. CString& strOut) // out
  635. {
  636. LPVOID lpMsgBuf=NULL;
  637. if ( rc != SCESTATUS_SUCCESS ) {
  638. //
  639. // translate SCESTATUS into DWORD
  640. //
  641. DWORD win32 = SceStatusToDosError(rc);
  642. //
  643. // get error description of rc
  644. //
  645. //This is a safe usage. The function is responsible to allocate memery.
  646. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  647. NULL,
  648. win32,
  649. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  650. (LPTSTR)&lpMsgBuf,
  651. 0,
  652. NULL
  653. );
  654. }
  655. if ( lpMsgBuf != NULL ) {
  656. strOut = (LPTSTR)lpMsgBuf;
  657. LocalFree(lpMsgBuf);
  658. lpMsgBuf = NULL;
  659. } else {
  660. strOut.Empty();
  661. }
  662. CString strEx; //Raid #485372, yanggao, 11/30/2001
  663. switch(rc)
  664. {
  665. case SCESTATUS_INVALID_PARAMETER:
  666. case SCESTATUS_RECORD_NOT_FOUND:
  667. case SCESTATUS_INVALID_DATA:
  668. case SCESTATUS_OBJECT_EXIST:
  669. case SCESTATUS_PROFILE_NOT_FOUND:
  670. strEx.LoadString(IDS_OBJECT_FAILED_NOTE);
  671. break;
  672. case SCESTATUS_ACCESS_DENIED:
  673. case SCESTATUS_CANT_DELETE:
  674. strEx.LoadString(IDS_SAVE_FAILED_NOTE);
  675. break;
  676. case SCESTATUS_PREFIX_OVERFLOW:
  677. case SCESTATUS_ALREADY_RUNNING:
  678. case SCESTATUS_OTHER_ERROR:
  679. case SCESTATUS_BUFFER_TOO_SMALL:
  680. case SCESTATUS_BAD_FORMAT:
  681. case SCESTATUS_NOT_ENOUGH_RESOURCE:
  682. default:
  683. strEx.Empty();
  684. break;
  685. }
  686. if( strEx.IsEmpty() )
  687. {
  688. strOut += mes;
  689. }
  690. else
  691. {
  692. strOut = strOut + mes + L" " + strEx;
  693. }
  694. strOut += L"\n";
  695. //
  696. // Loop through the error buffers and append each of them to strOut
  697. //
  698. for (PSCE_ERROR_LOG_INFO pErr = errBuf;
  699. pErr != NULL;
  700. pErr = pErr->next) {
  701. if (NULL == pErr) {
  702. continue;
  703. }
  704. if ( pErr->rc != NO_ERROR) {
  705. //This is a safe usage. The function is responsible to allocate memery.
  706. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  707. NULL,
  708. pErr->rc,
  709. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  710. (LPTSTR)&lpMsgBuf,
  711. 0,
  712. NULL
  713. );
  714. if ( lpMsgBuf ) {
  715. strOut += (LPTSTR)lpMsgBuf;
  716. LocalFree(lpMsgBuf);
  717. lpMsgBuf = NULL;
  718. }
  719. }
  720. if (pErr->buffer) {
  721. strOut += pErr->buffer;
  722. strOut += L"\n";
  723. }
  724. }
  725. }
  726. DWORD
  727. FormatDBErrorMessage(
  728. SCESTATUS sceStatus,
  729. LPCTSTR pszDatabase,
  730. CString &strOut
  731. )
  732. {
  733. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  734. UINT uErr = 0;
  735. switch (sceStatus) {
  736. case SCESTATUS_SUCCESS:
  737. return ERROR_INVALID_PARAMETER;
  738. case SCESTATUS_INVALID_DATA:
  739. uErr = IDS_DBERR_INVALID_DATA;
  740. break;
  741. case SCESTATUS_PROFILE_NOT_FOUND:
  742. uErr = IDS_DBERR5_PROFILE_NOT_FOUND;
  743. break;
  744. case SCESTATUS_BAD_FORMAT:
  745. uErr = IDS_DBERR_BAD_FORMAT;
  746. break;
  747. case SCESTATUS_BUFFER_TOO_SMALL:
  748. case SCESTATUS_NOT_ENOUGH_RESOURCE:
  749. uErr = IDS_DBERR_NOT_ENOUGH_RESOURCE;
  750. break;
  751. case SCESTATUS_ACCESS_DENIED:
  752. uErr = IDS_DBERR5_ACCESS_DENIED;
  753. break;
  754. case SCESTATUS_NO_TEMPLATE_GIVEN:
  755. uErr = IDS_DBERR_NO_TEMPLATE_GIVEN;
  756. break;
  757. case SCESTATUS_SPECIAL_ACCOUNT: //Raid #589139, DCR, yanggao, 4/10/2002.
  758. uErr = IDS_ERR_PRIVILEGE; //.Net use IDS_ERR_PRIVILEGE instead of IDS_DBERR5_ACCESS_DENIED which is used for XPSP1.
  759. break;
  760. case ERROR_NONE_MAPPED: //Raid #625342
  761. uErr = IDS_NO_ACCOUNT_MAP;
  762. break;
  763. default:
  764. uErr = IDS_DBERR_OTHER_ERROR;
  765. }
  766. if ( strOut.LoadString(uErr) ) {
  767. return ERROR_SUCCESS;
  768. }
  769. return ERROR_INVALID_PARAMETER;
  770. }
  771. DWORD SceStatusToDosError(SCESTATUS SceStatus)
  772. {
  773. switch (SceStatus) {
  774. case SCESTATUS_SUCCESS:
  775. return(NO_ERROR);
  776. case SCESTATUS_OTHER_ERROR:
  777. return(ERROR_EXTENDED_ERROR);
  778. case SCESTATUS_INVALID_PARAMETER:
  779. return(ERROR_INVALID_PARAMETER);
  780. case SCESTATUS_RECORD_NOT_FOUND:
  781. return(ERROR_RESOURCE_DATA_NOT_FOUND);
  782. case SCESTATUS_INVALID_DATA:
  783. return(ERROR_INVALID_DATA);
  784. case SCESTATUS_OBJECT_EXIST:
  785. return(ERROR_FILE_EXISTS);
  786. case SCESTATUS_BUFFER_TOO_SMALL:
  787. return(ERROR_INSUFFICIENT_BUFFER);
  788. case SCESTATUS_PROFILE_NOT_FOUND:
  789. return(ERROR_FILE_NOT_FOUND);
  790. case SCESTATUS_BAD_FORMAT:
  791. return(ERROR_BAD_FORMAT);
  792. case SCESTATUS_NOT_ENOUGH_RESOURCE:
  793. return(ERROR_NOT_ENOUGH_MEMORY);
  794. case SCESTATUS_ACCESS_DENIED:
  795. case SCESTATUS_SPECIAL_ACCOUNT: //Raid #589139, DCR, yanggao, 4/10/2002.
  796. return(ERROR_ACCESS_DENIED);
  797. case SCESTATUS_CANT_DELETE:
  798. return(ERROR_CURRENT_DIRECTORY);
  799. case SCESTATUS_PREFIX_OVERFLOW:
  800. return(ERROR_BUFFER_OVERFLOW);
  801. case SCESTATUS_ALREADY_RUNNING:
  802. return(ERROR_SERVICE_ALREADY_RUNNING);
  803. default:
  804. return(ERROR_EXTENDED_ERROR);
  805. }
  806. }
  807. //+--------------------------------------------------------------------------
  808. //
  809. // Function: CreateNewProfile
  810. //
  811. // Synopsis: Create a new tempate with default values in the ProfileName location
  812. //
  813. // Returns: TRUE if a template ends up in the ProfileName file
  814. // FALSE otherwise
  815. //
  816. // History:
  817. //
  818. //---------------------------------------------------------------------------
  819. BOOL CreateNewProfile(CString ProfileName,PSCE_PROFILE_INFO *ppspi)
  820. {
  821. SCESTATUS status;
  822. SCE_PROFILE_INFO *pTemplate;
  823. //
  824. // profile name must end with .inf
  825. //
  826. int nLen = ProfileName.GetLength ();
  827. // start searching at the last 4 position
  828. if ( ProfileName.Find (L".inf", nLen-4) != nLen-4 )
  829. {
  830. return FALSE;
  831. }
  832. //
  833. // if the profile already exists then we don't need to do anything
  834. //
  835. if ( FilePathExist( (LPCTSTR)ProfileName, FALSE, 0) ) {
  836. return TRUE;
  837. }
  838. //
  839. // Make sure the directory for the profile exists
  840. //
  841. status = SceCreateDirectory(ProfileName,FALSE,NULL);
  842. if (SCESTATUS_SUCCESS != status) {
  843. return FALSE;
  844. }
  845. pTemplate = (SCE_PROFILE_INFO*)LocalAlloc(LPTR,sizeof(SCE_PROFILE_INFO));
  846. if (!pTemplate) {
  847. return FALSE;
  848. }
  849. #ifdef FILL_WITH_DEFAULT_VALUES
  850. SCE_PROFILE_INFO *pDefault = GetDefaultTemplate();
  851. //
  852. // Fill with default values
  853. //
  854. pTemplate->Type = SCE_ENGINE_SCP;
  855. #define CD(X) pTemplate->X = pDefault->X;
  856. #else // !FILL_WITH_DEFAULT_VALUES
  857. #define CD(X) pTemplate->X = SCE_NO_VALUE;
  858. #endif // !FILL_WITH_DEFAULT_VALUES
  859. CD(MinimumPasswordAge);
  860. CD(MaximumPasswordAge);
  861. CD(MinimumPasswordLength);
  862. CD(PasswordComplexity);
  863. CD(PasswordHistorySize);
  864. CD(LockoutBadCount);
  865. CD(ResetLockoutCount);
  866. CD(LockoutDuration);
  867. CD(RequireLogonToChangePassword);
  868. CD(ForceLogoffWhenHourExpire);
  869. CD(EnableAdminAccount);
  870. CD(EnableGuestAccount);
  871. // These members aren't declared in NT4
  872. CD(ClearTextPassword);
  873. CD(AuditDSAccess);
  874. CD(AuditAccountLogon);
  875. CD(LSAAnonymousNameLookup);
  876. CD(MaximumLogSize[0]);
  877. CD(MaximumLogSize[1]);
  878. CD(MaximumLogSize[2]);
  879. CD(AuditLogRetentionPeriod[0]);
  880. CD(AuditLogRetentionPeriod[1]);
  881. CD(AuditLogRetentionPeriod[2]);
  882. CD(RetentionDays[0]);
  883. CD(RetentionDays[1]);
  884. CD(RetentionDays[2]);
  885. CD(RestrictGuestAccess[0]);
  886. CD(RestrictGuestAccess[1]);
  887. CD(RestrictGuestAccess[2]);
  888. CD(AuditSystemEvents);
  889. CD(AuditLogonEvents);
  890. CD(AuditObjectAccess);
  891. CD(AuditPrivilegeUse);
  892. CD(AuditPolicyChange);
  893. CD(AuditAccountManage);
  894. CD(AuditProcessTracking);
  895. #ifdef FILL_WITH_DEFAULT_VALUES
  896. //
  897. // These two are strings rather than DWORDs
  898. //
  899. if (pDefault->NewAdministratorName) {
  900. pTemplate->NewAdministratorName =
  901. (LPTSTR) LocalAlloc(LPTR,(lstrlen(pDefault->NewAdministratorName)+1)*sizeof(TCHAR));
  902. if (pTemplate->NewAdministratorName) {
  903. //This may not be a safe usage. pTemplate->NewAdministratorName and pDefault->NewAdministratorName are both PWSTR. Consider fix.
  904. lstrcpy(pTemplate->NewAdministratorName,
  905. pDefault->NewAdministratorName);
  906. }
  907. }
  908. if (pDefault->NewGuestName) {
  909. pTemplate->NewGuestName =
  910. (LPTSTR) LocalAlloc(LPTR,(lstrlen(pDefault->NewGuestName)+1)*sizeof(TCHAR));
  911. if (pTemplate->NewGuestName) {
  912. //This may not be a safe usage. pTemplate->NewGuestName and pDefault->NewGuestName are both PWSTR. Consider fix.
  913. lstrcpy(pTemplate->NewGuestName,
  914. pDefault->NewGuestName);
  915. }
  916. }
  917. #endif // FILL_WITH_DEFAULT_VALUES
  918. #undef CD
  919. status = SceWriteSecurityProfileInfo(ProfileName,
  920. AREA_ALL,
  921. pTemplate,
  922. NULL);
  923. if (ppspi) {
  924. *ppspi = pTemplate;
  925. } else {
  926. SceFreeProfileMemory(pTemplate);
  927. }
  928. return (SCESTATUS_SUCCESS == status);
  929. }
  930. BOOL
  931. VerifyKerberosInfo(PSCE_PROFILE_INFO pspi) {
  932. if (pspi->pKerberosInfo) {
  933. return TRUE;
  934. }
  935. pspi->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO)
  936. LocalAlloc(LPTR,sizeof(SCE_KERBEROS_TICKET_INFO));
  937. if (pspi->pKerberosInfo) {
  938. pspi->pKerberosInfo->MaxTicketAge = SCE_NO_VALUE;
  939. pspi->pKerberosInfo->MaxRenewAge = SCE_NO_VALUE;
  940. pspi->pKerberosInfo->MaxServiceAge = SCE_NO_VALUE;
  941. pspi->pKerberosInfo->MaxClockSkew = SCE_NO_VALUE;
  942. pspi->pKerberosInfo->TicketValidateClient = SCE_NO_VALUE;
  943. return TRUE;
  944. }
  945. return FALSE;
  946. }
  947. BOOL
  948. SetProfileInfo(LONG_PTR dwItem,LONG_PTR dwNew,PEDITTEMPLATE pEdit) {
  949. if (!pEdit) {
  950. return FALSE;
  951. }
  952. pEdit->SetDirty(AREA_SECURITY_POLICY);
  953. switch (dwItem) {
  954. case IDS_MAX_PAS_AGE:
  955. pEdit->pTemplate->MaximumPasswordAge = (DWORD)PtrToUlong((PVOID)dwNew);
  956. break;
  957. case IDS_MIN_PAS_AGE:
  958. pEdit->pTemplate->MinimumPasswordAge = (DWORD)PtrToUlong((PVOID)dwNew);
  959. break;
  960. case IDS_MIN_PAS_LEN:
  961. pEdit->pTemplate->MinimumPasswordLength = (DWORD)PtrToUlong((PVOID)dwNew);
  962. break;
  963. case IDS_PAS_UNIQUENESS:
  964. pEdit->pTemplate->PasswordHistorySize = (DWORD)PtrToUlong((PVOID)dwNew);
  965. break;
  966. case IDS_PAS_COMPLEX:
  967. pEdit->pTemplate->PasswordComplexity = (DWORD)PtrToUlong((PVOID)dwNew);
  968. break;
  969. case IDS_REQ_LOGON:
  970. pEdit->pTemplate->RequireLogonToChangePassword = (DWORD)PtrToUlong((PVOID)dwNew);
  971. break;
  972. case IDS_LOCK_COUNT:
  973. pEdit->pTemplate->LockoutBadCount = (DWORD)PtrToUlong((PVOID)dwNew);
  974. break;
  975. case IDS_LOCK_RESET_COUNT:
  976. pEdit->pTemplate->ResetLockoutCount = (DWORD)PtrToUlong((PVOID)dwNew);
  977. break;
  978. case IDS_LOCK_DURATION:
  979. pEdit->pTemplate->LockoutDuration = (DWORD)PtrToUlong((PVOID)dwNew);
  980. break;
  981. case IDS_FORCE_LOGOFF:
  982. pEdit->pTemplate->ForceLogoffWhenHourExpire = (DWORD)PtrToUlong((PVOID)dwNew);
  983. break;
  984. case IDS_ENABLE_ADMIN:
  985. pEdit->pTemplate->EnableAdminAccount = (DWORD)PtrToUlong((PVOID)dwNew);
  986. break;
  987. case IDS_ENABLE_GUEST:
  988. pEdit->pTemplate->EnableGuestAccount = (DWORD)PtrToUlong((PVOID)dwNew);
  989. break;
  990. case IDS_LSA_ANON_LOOKUP:
  991. pEdit->pTemplate->LSAAnonymousNameLookup = (DWORD)PtrToUlong((PVOID)dwNew);
  992. break;
  993. case IDS_NEW_ADMIN:
  994. if (pEdit->pTemplate->NewAdministratorName) {
  995. LocalFree(pEdit->pTemplate->NewAdministratorName);
  996. }
  997. if (dwNew && (dwNew != (LONG_PTR)ULongToPtr(SCE_NO_VALUE))) {
  998. pEdit->pTemplate->NewAdministratorName = (PWSTR)LocalAlloc(LPTR,(lstrlen((PWSTR)dwNew)+1)*sizeof(WCHAR));
  999. if (pEdit->pTemplate->NewAdministratorName) {
  1000. //This may not be a safe usage. pTemplate->NewAdministratorName and dwNew are both PWSTR. Consider fix.
  1001. lstrcpy(pEdit->pTemplate->NewAdministratorName,(PWSTR)dwNew);
  1002. }
  1003. } else {
  1004. pEdit->pTemplate->NewAdministratorName = NULL;
  1005. }
  1006. break;
  1007. case IDS_NEW_GUEST:
  1008. if (pEdit->pTemplate->NewGuestName) {
  1009. LocalFree(pEdit->pTemplate->NewGuestName);
  1010. }
  1011. if (dwNew && (dwNew != (LONG_PTR)ULongToPtr(SCE_NO_VALUE))) {
  1012. pEdit->pTemplate->NewGuestName = (PWSTR)LocalAlloc(LPTR,(lstrlen((PWSTR)dwNew)+1)*sizeof(WCHAR));
  1013. if (pEdit->pTemplate->NewGuestName) {
  1014. //This may not be a safe usage. pTemplate->NewGuestName and dwNew are both PWSTR. Consider fix.
  1015. lstrcpy(pEdit->pTemplate->NewGuestName,(PWSTR)dwNew);
  1016. }
  1017. } else {
  1018. pEdit->pTemplate->NewGuestName = NULL;
  1019. }
  1020. break;
  1021. case IDS_SYS_LOG_MAX:
  1022. pEdit->pTemplate->MaximumLogSize[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew);
  1023. break;
  1024. case IDS_SYS_LOG_RET:
  1025. pEdit->pTemplate->AuditLogRetentionPeriod[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew);
  1026. break;
  1027. case IDS_SYS_LOG_DAYS:
  1028. pEdit->pTemplate->RetentionDays[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew);
  1029. break;
  1030. case IDS_SEC_LOG_MAX:
  1031. pEdit->pTemplate->MaximumLogSize[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew);
  1032. break;
  1033. case IDS_SEC_LOG_RET:
  1034. pEdit->pTemplate->AuditLogRetentionPeriod[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew);
  1035. break;
  1036. case IDS_SEC_LOG_DAYS:
  1037. pEdit->pTemplate->RetentionDays[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew);
  1038. break;
  1039. case IDS_APP_LOG_MAX:
  1040. pEdit->pTemplate->MaximumLogSize[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew);
  1041. break;
  1042. case IDS_APP_LOG_RET:
  1043. pEdit->pTemplate->AuditLogRetentionPeriod[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew);
  1044. break;
  1045. case IDS_APP_LOG_DAYS:
  1046. pEdit->pTemplate->RetentionDays[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew);
  1047. break;
  1048. case IDS_SYSTEM_EVENT:
  1049. pEdit->pTemplate->AuditSystemEvents = (DWORD)PtrToUlong((PVOID)dwNew);
  1050. break;
  1051. case IDS_LOGON_EVENT:
  1052. pEdit->pTemplate->AuditLogonEvents = (DWORD)PtrToUlong((PVOID)dwNew);
  1053. break;
  1054. case IDS_OBJECT_ACCESS:
  1055. pEdit->pTemplate->AuditObjectAccess = (DWORD)PtrToUlong((PVOID)dwNew);
  1056. break;
  1057. case IDS_PRIVILEGE_USE:
  1058. pEdit->pTemplate->AuditPrivilegeUse = (DWORD)PtrToUlong((PVOID)dwNew);
  1059. break;
  1060. case IDS_POLICY_CHANGE:
  1061. pEdit->pTemplate->AuditPolicyChange = (DWORD)PtrToUlong((PVOID)dwNew);
  1062. break;
  1063. case IDS_ACCOUNT_MANAGE:
  1064. pEdit->pTemplate->AuditAccountManage = (DWORD)PtrToUlong((PVOID)dwNew);
  1065. break;
  1066. case IDS_PROCESS_TRACK:
  1067. pEdit->pTemplate->AuditProcessTracking = (DWORD)PtrToUlong((PVOID)dwNew);
  1068. break;
  1069. case IDS_DIRECTORY_ACCESS:
  1070. pEdit->pTemplate->AuditDSAccess = (DWORD)PtrToUlong((PVOID)dwNew);
  1071. break;
  1072. case IDS_ACCOUNT_LOGON:
  1073. pEdit->pTemplate->AuditAccountLogon = (DWORD)PtrToUlong((PVOID)dwNew);
  1074. break;
  1075. case IDS_SYS_LOG_GUEST:
  1076. pEdit->pTemplate->RestrictGuestAccess[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew);
  1077. break;
  1078. case IDS_SEC_LOG_GUEST:
  1079. pEdit->pTemplate->RestrictGuestAccess[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew);
  1080. break;
  1081. case IDS_APP_LOG_GUEST:
  1082. pEdit->pTemplate->RestrictGuestAccess[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew);
  1083. break;
  1084. case IDS_CLEAR_PASSWORD:
  1085. pEdit->pTemplate->ClearTextPassword = (DWORD)PtrToUlong((PVOID)dwNew);
  1086. break;
  1087. case IDS_KERBEROS_MAX_SERVICE:
  1088. if (VerifyKerberosInfo(pEdit->pTemplate)) {
  1089. pEdit->pTemplate->pKerberosInfo->MaxServiceAge = (DWORD)PtrToUlong((PVOID)dwNew);
  1090. }
  1091. break;
  1092. case IDS_KERBEROS_MAX_CLOCK:
  1093. if (VerifyKerberosInfo( pEdit->pTemplate)) {
  1094. pEdit->pTemplate->pKerberosInfo->MaxClockSkew = (DWORD)PtrToUlong((PVOID)dwNew);
  1095. }
  1096. break;
  1097. case IDS_KERBEROS_VALIDATE_CLIENT:
  1098. if (VerifyKerberosInfo( pEdit->pTemplate)) {
  1099. pEdit->pTemplate->pKerberosInfo->TicketValidateClient = (DWORD)PtrToUlong((PVOID)dwNew);
  1100. }
  1101. break;
  1102. case IDS_KERBEROS_MAX_AGE:
  1103. if (VerifyKerberosInfo( pEdit->pTemplate)) {
  1104. pEdit->pTemplate->pKerberosInfo->MaxTicketAge = (DWORD)PtrToUlong((PVOID)dwNew);
  1105. }
  1106. break;
  1107. case IDS_KERBEROS_RENEWAL:
  1108. if (VerifyKerberosInfo( pEdit->pTemplate)) {
  1109. pEdit->pTemplate->pKerberosInfo->MaxRenewAge = (DWORD)PtrToUlong((PVOID)dwNew);
  1110. }
  1111. break;
  1112. default:
  1113. return FALSE;
  1114. }
  1115. return TRUE;
  1116. }
  1117. //
  1118. // FUNCTION: ErrorHandlerEx(WORD, LPSTR)
  1119. //
  1120. // PURPOSE: Calls GetLastError() and uses FormatMessage() to display the
  1121. // textual information of the error code along with the file
  1122. // and line number.
  1123. //
  1124. // PARAMETERS:
  1125. // wLine - line number where the error occured
  1126. // lpszFile - file where the error occured
  1127. //
  1128. // RETURN VALUE:
  1129. // none
  1130. //
  1131. // COMMENTS:
  1132. // This function has a macro ErrorHandler() which handles filling in
  1133. // the line number and file name where the error occured. ErrorHandler()
  1134. // is always used instead of calling this function directly.
  1135. //
  1136. void ErrorHandlerEx( WORD wLine, LPTSTR lpszFile )
  1137. {
  1138. LPVOID lpvMessage;
  1139. DWORD dwError;
  1140. CString szBuffer;
  1141. // The the text of the error message
  1142. //This is a safe usage.
  1143. dwError = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1144. FORMAT_MESSAGE_FROM_SYSTEM,
  1145. NULL,
  1146. GetLastError(),
  1147. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  1148. (LPTSTR)&lpvMessage,
  1149. 0,
  1150. NULL);
  1151. // Check to see if an error occured calling FormatMessage()
  1152. if (0 == dwError) {
  1153. //This is not a safe usage. avoid using wsprintf. Raid #555867. Yanggao.
  1154. szBuffer.Format(TEXT("An error occured calling FormatMessage().")
  1155. TEXT("Error Code %d"), GetLastError());
  1156. MessageBox(NULL, szBuffer, TEXT("Security Configuration Editor"), MB_ICONSTOP |
  1157. MB_ICONEXCLAMATION);
  1158. return;
  1159. }
  1160. // Display the error message
  1161. //This is not a safe usage. avoid using wsprinf. Raid #555867. Yanggao.
  1162. szBuffer.Format(TEXT("Generic, Line=%d, File=%s"), wLine, lpszFile);
  1163. MessageBox(NULL, (LPTSTR)lpvMessage, szBuffer, MB_ICONEXCLAMATION | MB_OK);
  1164. return;
  1165. }
  1166. BOOL
  1167. GetSceStatusString(SCESTATUS status, CString *strStatus) {
  1168. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1169. if (!strStatus || (status > SCESTATUS_SERVICE_NOT_SUPPORT)) {
  1170. return false;
  1171. }
  1172. return strStatus->LoadString(status + IDS_SCESTATUS_SUCCESS);
  1173. }
  1174. //+---------------------------------------------------------------------------------------------
  1175. // EnumLangProc
  1176. //
  1177. // Creates the lanuage ID for the resource attached to the DLL. The function only enumerates
  1178. // on lanuage.
  1179. //
  1180. // Arguments: - See help on EnumResLangProc in the SDK Doc.
  1181. //
  1182. // Returns: - Returns FALSE because we only want the very first lanuage enumerated.
  1183. //
  1184. //+---------------------------------------------------------------------------------------------
  1185. BOOL CALLBACK EnumLangProc(
  1186. HMODULE hMod,
  1187. LPCTSTR pszType,
  1188. LPCTSTR pszName,
  1189. WORD wIDLanguage,
  1190. LONG_PTR lParam
  1191. )
  1192. {
  1193. //
  1194. // We only want the very first enumerated type, so create the language ID
  1195. // and exit this enumeration.
  1196. //
  1197. *((DWORD *)lParam) = wIDLanguage;
  1198. return FALSE;
  1199. }
  1200. bool
  1201. GetRightDisplayName(LPCTSTR szSystemName, LPCTSTR szName, LPTSTR szDisp, LPDWORD lpcbDisp) {
  1202. LPTSTR szLCName;
  1203. DWORD dwLang;
  1204. int i;
  1205. if (!szDisp || !szName) {
  1206. return false;
  1207. }
  1208. //
  1209. // Enumerate our resource to find out what language the resource is in.
  1210. //
  1211. DWORD dwDefaultLang;
  1212. dwDefaultLang = GetUserDefaultUILanguage();
  1213. LCID localeID = MAKELCID(dwDefaultLang, SORT_DEFAULT);
  1214. LCID langDefault = GetThreadLocale();
  1215. SetThreadLocale( localeID );
  1216. *lpcbDisp = dwDefaultLang;
  1217. DWORD cBufSize=*lpcbDisp;
  1218. BOOL bFound;
  1219. bFound = LookupPrivilegeDisplayName(szSystemName,szName,szDisp,lpcbDisp,&dwLang);
  1220. if ( bFound && dwDefaultLang != dwLang && szSystemName ) {
  1221. // not the language I am looking for
  1222. // search on local system
  1223. *lpcbDisp = cBufSize;
  1224. bFound = LookupPrivilegeDisplayName(NULL,szName,szDisp,lpcbDisp,&dwLang);
  1225. }
  1226. SetThreadLocale(langDefault);
  1227. //Prefast warning 400: Using 'lstrcmpiW' to perform a case-insensitive compare to constant string.
  1228. //Yields unexpected result in non-English locales. Currently they are always English locale.
  1229. if (!bFound) {
  1230. if (0 == _wcsicmp(szName,L"senetworklogonright")) {
  1231. LoadString(AfxGetInstanceHandle(),IDS_SE_NETWORK_LOGON_RIGHT,szDisp,*lpcbDisp);
  1232. } else if (0 == _wcsicmp(szName,L"seinteractivelogonright")) {
  1233. LoadString(AfxGetInstanceHandle(),IDS_SE_INTERACTIVE_LOGON_RIGHT,szDisp,*lpcbDisp);
  1234. } else if (0 == _wcsicmp(szName,L"sebatchlogonright")) {
  1235. LoadString(AfxGetInstanceHandle(),IDS_SE_BATCH_LOGON_RIGHT,szDisp,*lpcbDisp);
  1236. } else if (0 == _wcsicmp(szName,L"seservicelogonright")) {
  1237. LoadString(AfxGetInstanceHandle(),IDS_SE_SERVICE_LOGON_RIGHT,szDisp,*lpcbDisp);
  1238. } else if (0 == _wcsicmp(szName,L"sedenyinteractivelogonright")) {
  1239. LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_LOCALLY,szDisp,*lpcbDisp);
  1240. } else if (0 == _wcsicmp(szName,L"sedenynetworklogonright")) {
  1241. LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_NETWORK,szDisp,*lpcbDisp);
  1242. } else if (0 == _wcsicmp(szName,L"sedenyservicelogonright")) {
  1243. LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_SERVICE,szDisp,*lpcbDisp);
  1244. } else if (0 == _wcsicmp(szName,L"sedenybatchlogonright")) {
  1245. LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_BATCH,szDisp,*lpcbDisp);
  1246. } else if (0 == _wcsicmp(szName,L"sedenyremoteinteractivelogonright")) {
  1247. LoadString(AfxGetInstanceHandle(),IDS_DENY_REMOTE_INTERACTIVE_LOGON,szDisp,*lpcbDisp);
  1248. } else if (0 == _wcsicmp(szName,L"seremoteinteractivelogonright")) {
  1249. LoadString(AfxGetInstanceHandle(),IDS_REMOTE_INTERACTIVE_LOGON,szDisp,*lpcbDisp);
  1250. } else {
  1251. //This is not a safe usage. Make sure szDisp is terminated. Raid #553113, yanggao
  1252. lstrcpyn(szDisp,szName,*lpcbDisp-1);
  1253. }
  1254. }
  1255. return true;
  1256. }
  1257. #define DPI(X) {str.Format(L"%S: %d\n",#X,pInfo->X);OutputDebugString(str);}
  1258. void DumpProfileInfo(PSCE_PROFILE_INFO pInfo) {
  1259. CString str;
  1260. PSCE_PRIVILEGE_ASSIGNMENT ppa;
  1261. PSCE_NAME_LIST pName;
  1262. PSCE_GROUP_MEMBERSHIP pgm;
  1263. if (!pInfo) {
  1264. return;
  1265. }
  1266. DPI(MinimumPasswordAge);
  1267. DPI(MaximumPasswordAge);
  1268. DPI(MinimumPasswordLength);
  1269. DPI(PasswordComplexity);
  1270. DPI(PasswordHistorySize);
  1271. DPI(LockoutBadCount);
  1272. DPI(ResetLockoutCount);
  1273. DPI(LockoutDuration);
  1274. DPI(RequireLogonToChangePassword);
  1275. DPI(ForceLogoffWhenHourExpire);
  1276. DPI(EnableAdminAccount);
  1277. DPI(EnableGuestAccount);
  1278. DPI(ClearTextPassword);
  1279. DPI(AuditDSAccess);
  1280. DPI(AuditAccountLogon);
  1281. DPI(LSAAnonymousNameLookup);
  1282. // DPI(EventAuditingOnOff);
  1283. DPI(AuditSystemEvents);
  1284. DPI(AuditLogonEvents);
  1285. DPI(AuditObjectAccess);
  1286. DPI(AuditPrivilegeUse);
  1287. DPI(AuditPolicyChange);
  1288. DPI(AuditAccountManage);
  1289. DPI(AuditProcessTracking);
  1290. if (pInfo->NewGuestName) {
  1291. OutputDebugString(L"NewGuestName: ");
  1292. if ((DWORD_PTR)ULongToPtr(SCE_NO_VALUE) == (DWORD_PTR)pInfo->NewGuestName) {
  1293. OutputDebugString(L"[[undefined]]");
  1294. } else {
  1295. OutputDebugString(pInfo->NewGuestName);
  1296. }
  1297. OutputDebugString(L"\n");
  1298. } else {
  1299. OutputDebugString(L"NewGuestName: [[absent]]\n");
  1300. }
  1301. if (pInfo->NewAdministratorName) {
  1302. OutputDebugString(L"NewAdministratorName: ");
  1303. if ((DWORD_PTR)ULongToPtr(SCE_NO_VALUE) == (DWORD_PTR)pInfo->NewAdministratorName) {
  1304. OutputDebugString(L"[[undefined]]");
  1305. } else {
  1306. OutputDebugString(pInfo->NewAdministratorName);
  1307. }
  1308. OutputDebugString(L"\n");
  1309. } else {
  1310. OutputDebugString(L"NewGuestName: [[absent]]\n");
  1311. }
  1312. OutputDebugString(L"\n");
  1313. switch(pInfo->Type) {
  1314. case SCE_ENGINE_SCP:
  1315. ppa = pInfo->OtherInfo.scp.u.pInfPrivilegeAssignedTo;
  1316. break;
  1317. case SCE_ENGINE_SAP:
  1318. ppa = pInfo->OtherInfo.sap.pPrivilegeAssignedTo;
  1319. break;
  1320. case SCE_ENGINE_SMP:
  1321. ppa = pInfo->OtherInfo.smp.pPrivilegeAssignedTo;
  1322. break;
  1323. case SCE_ENGINE_SYSTEM:
  1324. ppa = NULL;
  1325. break;
  1326. default:
  1327. OutputDebugString(L"!!!Unknown Template Type!!!\n");
  1328. ppa = NULL;
  1329. break;
  1330. }
  1331. while(ppa) {
  1332. OutputDebugString(ppa->Name);
  1333. OutputDebugString(L":");
  1334. pName = ppa->AssignedTo;
  1335. while(pName) {
  1336. OutputDebugString(pName->Name);
  1337. OutputDebugString(L",");
  1338. pName = pName->Next;
  1339. }
  1340. ppa = ppa->Next;
  1341. OutputDebugString(L"\n");
  1342. }
  1343. OutputDebugString(L"\n");
  1344. PSCE_REGISTRY_VALUE_INFO aRegValues;
  1345. for(DWORD i = 0; i< pInfo->RegValueCount;i++) {
  1346. OutputDebugString(pInfo->aRegValues[i].FullValueName);
  1347. OutputDebugString(L":");
  1348. switch(pInfo->aRegValues[i].ValueType) {
  1349. case SCE_REG_DISPLAY_STRING:
  1350. OutputDebugString(pInfo->aRegValues[i].Value);
  1351. break;
  1352. default:
  1353. str.Format(L"%d",(ULONG_PTR)pInfo->aRegValues[i].Value);
  1354. OutputDebugString(str);
  1355. }
  1356. OutputDebugString(L"\n");
  1357. }
  1358. OutputDebugString(L"\n");
  1359. pgm = pInfo->pGroupMembership;
  1360. while(pgm) {
  1361. OutputDebugString(L"\nGROUP: ");
  1362. OutputDebugString(pgm->GroupName);
  1363. OutputDebugString(L"\nMembers: ");
  1364. pName = pgm->pMembers;
  1365. while(pName) {
  1366. OutputDebugString(pName->Name);
  1367. OutputDebugString(L",");
  1368. pName = pName->Next;
  1369. }
  1370. OutputDebugString(L"\nMember Of: ");
  1371. pName = pgm->pMemberOf;
  1372. while(pName) {
  1373. OutputDebugString(pName->Name);
  1374. OutputDebugString(L",");
  1375. pName = pName->Next;
  1376. }
  1377. OutputDebugString(L"\n");
  1378. pgm = pgm->Next;
  1379. }
  1380. OutputDebugString(L"\nGROUP: ");
  1381. }
  1382. HRESULT MyMakeSelfRelativeSD(
  1383. PSECURITY_DESCRIPTOR psdOriginal,
  1384. PSECURITY_DESCRIPTOR* ppsdNew )
  1385. {
  1386. ASSERT( NULL != psdOriginal );
  1387. if ( NULL == psdOriginal || NULL == ppsdNew ) {
  1388. return E_INVALIDARG;
  1389. }
  1390. // we have to find out whether the original is already self-relative
  1391. SECURITY_DESCRIPTOR_CONTROL sdc = 0;
  1392. DWORD dwRevision = 0;
  1393. if ( !GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) ) {
  1394. ASSERT( FALSE );
  1395. DWORD err = GetLastError();
  1396. return HRESULT_FROM_WIN32( err );
  1397. }
  1398. DWORD cb = GetSecurityDescriptorLength( psdOriginal ) + 20;
  1399. PSECURITY_DESCRIPTOR psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR)LocalAlloc( LMEM_ZEROINIT, cb );
  1400. if (NULL == psdSelfRelativeCopy) {
  1401. return E_UNEXPECTED; // just in case the exception is ignored
  1402. }
  1403. if ( sdc & SE_SELF_RELATIVE )
  1404. // the original is in self-relative format, just byte-copy it
  1405. {
  1406. //This is a safe usage.
  1407. memcpy( psdSelfRelativeCopy, psdOriginal, cb - 20 );
  1408. } else if ( !MakeSelfRelativeSD( psdOriginal, psdSelfRelativeCopy, &cb ) )
  1409. // the original is in absolute format, convert-copy it
  1410. {
  1411. ASSERT( FALSE );
  1412. VERIFY( NULL == LocalFree( psdSelfRelativeCopy ) );
  1413. DWORD err = GetLastError();
  1414. return HRESULT_FROM_WIN32( err );
  1415. }
  1416. *ppsdNew = psdSelfRelativeCopy;
  1417. return S_OK;
  1418. }
  1419. PSCE_NAME_STATUS_LIST
  1420. MergeNameStatusList(PSCE_NAME_LIST pTemplate, PSCE_NAME_LIST pInspect)
  1421. {
  1422. PSCE_NAME_LIST pTemp1;
  1423. PSCE_NAME_STATUS_LIST plMerge=NULL, pTemp2;
  1424. SCESTATUS rc=SCESTATUS_SUCCESS;
  1425. for ( pTemp1=pTemplate; pTemp1; pTemp1=pTemp1->Next ) {
  1426. rc = SceAddToNameStatusList(&plMerge, pTemp1->Name, 0, MERGED_TEMPLATE );
  1427. if ( SCESTATUS_SUCCESS != rc )
  1428. break;
  1429. }
  1430. if ( SCESTATUS_SUCCESS == rc ) {
  1431. for ( pTemp1=pInspect; pTemp1; pTemp1=pTemp1->Next ) {
  1432. for ( pTemp2=plMerge; pTemp2 != NULL ; pTemp2=pTemp2->Next ) {
  1433. if ( pTemp2->Status & MERGED_INSPECT ) {
  1434. // this one is processed
  1435. continue;
  1436. } else if ( _wcsicmp(pTemp1->Name, pTemp2->Name) == 0 ) {
  1437. // find a match
  1438. pTemp2->Status = MERGED_TEMPLATE | MERGED_INSPECT;
  1439. break;
  1440. }
  1441. }
  1442. if ( !pTemp2 ) {
  1443. // did not find the match, add this one in
  1444. rc = SceAddToNameStatusList(&plMerge, pTemp1->Name, 0, MERGED_INSPECT );
  1445. if ( SCESTATUS_SUCCESS != rc )
  1446. break;
  1447. }
  1448. }
  1449. }
  1450. if ( SCESTATUS_SUCCESS == rc ) {
  1451. return plMerge;
  1452. } else {
  1453. SceFreeMemory(plMerge, SCE_STRUCT_NAME_STATUS_LIST);
  1454. return NULL;
  1455. }
  1456. }
  1457. SCESTATUS
  1458. ConvertMultiSzToDelim(
  1459. IN PWSTR pValue,
  1460. IN DWORD Len,
  1461. IN WCHAR DelimFrom,
  1462. IN WCHAR Delim
  1463. )
  1464. /*
  1465. Convert the multi-sz delimiter \0 to space
  1466. */
  1467. {
  1468. DWORD i;
  1469. for ( i=0; i<Len && pValue; i++) {
  1470. // if ( *(pValue+i) == L'\0' && *(pValue+i+1) != L'\0') {
  1471. if ( *(pValue+i) == DelimFrom && i+1 < Len &&
  1472. *(pValue+i+1) != L'\0' ) {
  1473. //
  1474. // a NULL delimiter is encounted and it's not the end (double NULL)
  1475. //
  1476. *(pValue+i) = Delim;
  1477. }
  1478. }
  1479. return(SCESTATUS_SUCCESS);
  1480. }
  1481. DWORD
  1482. SceRegEnumAllValues(
  1483. IN OUT PDWORD pCount,
  1484. IN OUT PSCE_REGISTRY_VALUE_INFO *paRegValues
  1485. )
  1486. /*
  1487. */
  1488. {
  1489. DWORD Win32Rc;
  1490. HKEY hKey=NULL;
  1491. PSCE_NAME_STATUS_LIST pnsList=NULL;
  1492. DWORD nAdded=0;
  1493. Win32Rc = RegOpenKeyEx(
  1494. HKEY_LOCAL_MACHINE,
  1495. SCE_ROOT_REGVALUE_PATH,
  1496. 0,
  1497. KEY_READ,
  1498. &hKey
  1499. );
  1500. DWORD cSubKeys = 0;
  1501. DWORD nMaxLen;
  1502. if ( Win32Rc == ERROR_SUCCESS ) {
  1503. //
  1504. // enumerate all subkeys of the key
  1505. //
  1506. Win32Rc = RegQueryInfoKey (
  1507. hKey,
  1508. NULL,
  1509. NULL,
  1510. NULL,
  1511. &cSubKeys,
  1512. &nMaxLen,
  1513. NULL,
  1514. NULL,
  1515. NULL,
  1516. NULL,
  1517. NULL,
  1518. NULL
  1519. );
  1520. }
  1521. if ( Win32Rc == ERROR_SUCCESS && cSubKeys > 0 ) {
  1522. PWSTR szName = (PWSTR)LocalAlloc(0, (nMaxLen+2)*sizeof(WCHAR));
  1523. if ( !szName ) {
  1524. Win32Rc = ERROR_NOT_ENOUGH_MEMORY;
  1525. } else {
  1526. DWORD BufSize;
  1527. DWORD index = 0;
  1528. DWORD RegType;
  1529. do {
  1530. BufSize = nMaxLen+1;
  1531. Win32Rc = RegEnumKeyEx(
  1532. hKey,
  1533. index,
  1534. szName,
  1535. &BufSize,
  1536. NULL,
  1537. NULL,
  1538. NULL,
  1539. NULL);
  1540. if ( ERROR_SUCCESS == Win32Rc ) {
  1541. index++;
  1542. //
  1543. // get the full registry key name and Valuetype
  1544. //
  1545. cSubKeys = REG_SZ;
  1546. PDWORD pType = &cSubKeys;
  1547. //
  1548. // query ValueType, if error, default REG_SZ
  1549. //
  1550. MyRegQueryValue( hKey,
  1551. szName,
  1552. SCE_REG_VALUE_TYPE,
  1553. (PVOID *)&pType,
  1554. &RegType );
  1555. if ( cSubKeys < REG_SZ || cSubKeys > REG_MULTI_SZ ) {
  1556. cSubKeys = REG_SZ;
  1557. }
  1558. //
  1559. // convert the path name
  1560. //
  1561. ConvertMultiSzToDelim(szName, BufSize, L'/', L'\\');
  1562. //
  1563. // compare with the input array, if not exist,
  1564. // add it
  1565. //
  1566. for ( DWORD i=0; i<*pCount; i++ ) {
  1567. if ( (*paRegValues)[i].FullValueName &&
  1568. _wcsicmp(szName, (*paRegValues)[i].FullValueName) == 0 ) {
  1569. break;
  1570. }
  1571. }
  1572. if ( i >= *pCount ) {
  1573. //
  1574. // did not find a match, add it
  1575. //
  1576. if ( SCESTATUS_SUCCESS != SceAddToNameStatusList(&pnsList,
  1577. szName,
  1578. BufSize,
  1579. cSubKeys) ) {
  1580. Win32Rc = ERROR_NOT_ENOUGH_MEMORY;
  1581. break;
  1582. }
  1583. nAdded++;
  1584. }
  1585. } else if ( ERROR_NO_MORE_ITEMS != Win32Rc ) {
  1586. break;
  1587. }
  1588. } while ( Win32Rc != ERROR_NO_MORE_ITEMS );
  1589. if ( Win32Rc == ERROR_NO_MORE_ITEMS ) {
  1590. Win32Rc = ERROR_SUCCESS;
  1591. }
  1592. //
  1593. // free the enumeration buffer
  1594. //
  1595. LocalFree(szName);
  1596. }
  1597. }
  1598. if ( hKey ) {
  1599. RegCloseKey(hKey);
  1600. }
  1601. if ( ERROR_SUCCESS == Win32Rc ) {
  1602. //
  1603. // add the name list to the output arrays
  1604. //
  1605. DWORD nNewCount = *pCount + nAdded;
  1606. PSCE_REGISTRY_VALUE_INFO aNewArray;
  1607. if ( nNewCount ) {
  1608. aNewArray = (PSCE_REGISTRY_VALUE_INFO)LocalAlloc(0, nNewCount*sizeof(SCE_REGISTRY_VALUE_INFO));
  1609. if ( aNewArray ) {
  1610. ZeroMemory(aNewArray, nNewCount * sizeof(SCE_REGISTRY_VALUE_INFO));
  1611. //This is a safe usage.
  1612. memcpy( aNewArray, *paRegValues, *pCount * sizeof( SCE_REGISTRY_VALUE_INFO ) );
  1613. DWORD i;
  1614. i=0;
  1615. for ( PSCE_NAME_STATUS_LIST pns=pnsList;
  1616. pns; pns=pns->Next ) {
  1617. if ( pns->Name && i < nAdded ) {
  1618. aNewArray[*pCount+i].FullValueName = pns->Name;
  1619. pns->Name = NULL;
  1620. aNewArray[*pCount+i].Value = NULL;
  1621. aNewArray[*pCount+i].ValueType = pns->Status;
  1622. aNewArray[*pCount+i].Status = SCE_STATUS_NOT_CONFIGURED;
  1623. i++;
  1624. }
  1625. }
  1626. //
  1627. // free the original array
  1628. // all components in the array are already transferred to the new array
  1629. //
  1630. LocalFree(*paRegValues);
  1631. *pCount = nNewCount;
  1632. *paRegValues = aNewArray;
  1633. } else {
  1634. Win32Rc = ERROR_NOT_ENOUGH_MEMORY;
  1635. }
  1636. }
  1637. }
  1638. //
  1639. // free the name status list
  1640. //
  1641. SceFreeMemory(pnsList, SCE_STRUCT_NAME_STATUS_LIST);
  1642. return( Win32Rc );
  1643. }
  1644. DWORD
  1645. GetGroupStatus(
  1646. DWORD status,
  1647. int flag
  1648. )
  1649. {
  1650. DWORD NewStatus;
  1651. switch ( flag ) {
  1652. case STATUS_GROUP_RECORD:
  1653. if (status & SCE_GROUP_STATUS_NC_MEMBERS) {
  1654. NewStatus = SCE_STATUS_NOT_CONFIGURED;
  1655. } else if ( (status & SCE_GROUP_STATUS_MEMBERS_MISMATCH) ||
  1656. (status & SCE_GROUP_STATUS_MEMBEROF_MISMATCH)) {
  1657. NewStatus = SCE_STATUS_MISMATCH;
  1658. } else if (status & SCE_GROUP_STATUS_NOT_ANALYZED) {
  1659. NewStatus = SCE_STATUS_NOT_ANALYZED;
  1660. } else if (status & SCE_GROUP_STATUS_ERROR_ANALYZED) {
  1661. NewStatus = SCE_STATUS_ERROR_NOT_AVAILABLE;
  1662. } else {
  1663. NewStatus = SCE_STATUS_GOOD;
  1664. }
  1665. break;
  1666. case STATUS_GROUP_MEMBERS:
  1667. if ( status & SCE_GROUP_STATUS_NOT_ANALYZED ) {
  1668. NewStatus = SCE_STATUS_NOT_ANALYZED; //do not display any status;
  1669. } else {
  1670. if ( status & SCE_GROUP_STATUS_NC_MEMBERS ) {
  1671. NewStatus = SCE_STATUS_NOT_CONFIGURED;
  1672. } else if ( status & SCE_GROUP_STATUS_MEMBERS_MISMATCH ) {
  1673. NewStatus = SCE_STATUS_MISMATCH;
  1674. } else if (status & SCE_GROUP_STATUS_ERROR_ANALYZED) {
  1675. NewStatus = SCE_STATUS_ERROR_NOT_AVAILABLE;
  1676. } else {
  1677. NewStatus = SCE_STATUS_GOOD;
  1678. }
  1679. }
  1680. break;
  1681. case STATUS_GROUP_MEMBEROF:
  1682. if ( status & SCE_GROUP_STATUS_NOT_ANALYZED ) {
  1683. NewStatus = SCE_STATUS_NOT_ANALYZED; // do not display any status;
  1684. } else {
  1685. if ( status & SCE_GROUP_STATUS_NC_MEMBEROF ) {
  1686. NewStatus = SCE_STATUS_NOT_CONFIGURED;
  1687. } else if ( status & SCE_GROUP_STATUS_MEMBEROF_MISMATCH ) {
  1688. NewStatus = SCE_STATUS_MISMATCH;
  1689. } else if (status & SCE_GROUP_STATUS_ERROR_ANALYZED) {
  1690. NewStatus = SCE_STATUS_ERROR_NOT_AVAILABLE;
  1691. } else {
  1692. NewStatus = SCE_STATUS_GOOD;
  1693. }
  1694. }
  1695. break;
  1696. default:
  1697. NewStatus = 0;
  1698. break;
  1699. }
  1700. return NewStatus;
  1701. }
  1702. //+--------------------------------------------------------------------------
  1703. //
  1704. // Function: AllocGetTempFileName
  1705. //
  1706. // Synopsis: Allocate and return a string with a temporary file name.
  1707. //
  1708. // Returns: The temporary file name, or 0 if a temp file can't be found
  1709. //
  1710. // History:
  1711. //
  1712. //---------------------------------------------------------------------------
  1713. LPTSTR
  1714. AllocGetTempFileName() {
  1715. DWORD dw;
  1716. CString strPath;
  1717. CString strFile;
  1718. LPTSTR szPath;
  1719. LPTSTR szFile;
  1720. //
  1721. // Get a temporary directory path in strPath
  1722. // If our buffer isn't large enough then keep reallocating until it is
  1723. //
  1724. dw = MAX_PATH;
  1725. do {
  1726. szPath = strPath.GetBuffer(dw);
  1727. dw = GetTempPath(MAX_PATH,szPath);
  1728. strPath.ReleaseBuffer();
  1729. } while (dw > (DWORD)strPath.GetLength() );
  1730. //
  1731. // Can't get a path to the temporary directory
  1732. //
  1733. if (!dw) {
  1734. return 0;
  1735. }
  1736. //
  1737. // Get a temporary file in that directory
  1738. //
  1739. szFile = strFile.GetBuffer(dw+MAX_PATH);
  1740. if (!GetTempFileName(szPath,L"SCE",0,szFile)) {
  1741. return 0;
  1742. }
  1743. strFile.ReleaseBuffer();
  1744. szFile = (LPTSTR)LocalAlloc(LPTR,(strFile.GetLength()+1)*sizeof(TCHAR));
  1745. if (!szFile) {
  1746. return 0;
  1747. }
  1748. //This is a safe usage.
  1749. lstrcpy(szFile,(LPCTSTR)strFile);
  1750. return szFile;
  1751. }
  1752. // If the given environment variable exists as the first part of the path,
  1753. // then the environment variable is inserted into the output buffer.
  1754. //
  1755. // Returns TRUE if pszResult is filled in.
  1756. //
  1757. // Example: Input -- C:\WINNT\SYSTEM32\FOO.TXT -and- lpEnvVar = %SYSTEMROOT%
  1758. // Output -- %SYSTEMROOT%\SYSTEM32\FOO.TXT
  1759. BOOL UnExpandEnvironmentString(LPCTSTR pszPath, LPCTSTR pszEnvVar, LPTSTR pszResult, UINT cbResult)
  1760. {
  1761. TCHAR szEnvVar[MAX_PATH];
  1762. if( !pszPath || !pszEnvVar || !pszResult ) //Raid #553113, yanggao.
  1763. return FALSE;
  1764. //This is not a safe usage. Make sure szEnvVar is terminated. Raid #553113, Yanggao.
  1765. memset(szEnvVar, '\0', (MAX_PATH)*sizeof(TCHAR));
  1766. DWORD dwEnvVar = ExpandEnvironmentStrings(pszEnvVar, szEnvVar, ARRAYSIZE(szEnvVar)) - 1; // don't count the NULL
  1767. if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
  1768. szEnvVar, dwEnvVar, pszPath, dwEnvVar) == 2) {
  1769. if (lstrlen(pszPath) + dwEnvVar < cbResult) {
  1770. //This is not a safe usage. validate pszPath, dwEnvVar, pszResult.
  1771. lstrcpy(pszResult, pszEnvVar);
  1772. lstrcat(pszResult, pszPath + dwEnvVar);
  1773. return TRUE;
  1774. }
  1775. }
  1776. return FALSE;
  1777. }
  1778. //+--------------------------------------------------------------------------
  1779. //
  1780. // Function: UnexpandEnvironmentVariables
  1781. //
  1782. // Synopsis: Given a path, contract any leading members to use matching
  1783. // environment variables, if any
  1784. //
  1785. // Arguments:
  1786. // [szPath] - The path to expand
  1787. //
  1788. // Returns: The newly allocated path (NULL if no changes are made)
  1789. //
  1790. // History:
  1791. //
  1792. //---------------------------------------------------------------------------
  1793. LPTSTR
  1794. UnexpandEnvironmentVariables(LPCTSTR szPath) {
  1795. UINT cbNew;
  1796. LPTSTR szNew;
  1797. LPTSTR mszEnvVars;
  1798. LPTSTR szEnvVar;
  1799. DWORD dwEnvType;
  1800. BOOL bExpanded;
  1801. CString strKey;
  1802. CString strValueName;
  1803. CString str;
  1804. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1805. if (!strKey.LoadString(IDS_SECEDIT_KEY) ||
  1806. !strValueName.LoadString(IDS_ENV_VARS_REG_VALUE)) {
  1807. return NULL;
  1808. }
  1809. //
  1810. // Allocate memory for the new path
  1811. //
  1812. cbNew = lstrlen(szPath)+MAX_PATH+1;
  1813. szNew = (LPTSTR) LocalAlloc(LPTR,cbNew * sizeof(TCHAR));
  1814. if (!szNew) {
  1815. return NULL;
  1816. }
  1817. //
  1818. // Get Vars to expand from the registry
  1819. //
  1820. mszEnvVars = NULL;
  1821. if (ERROR_SUCCESS != MyRegQueryValue(HKEY_LOCAL_MACHINE, // hKeyRoot
  1822. strKey, // SubKey
  1823. strValueName, // ValueName
  1824. (LPVOID *)&mszEnvVars, // Value
  1825. &dwEnvType)) { // Reg Type
  1826. //
  1827. // Can't get any variables to expand
  1828. //
  1829. LocalFree(szNew);
  1830. return NULL;
  1831. }
  1832. //
  1833. // We need a multi-sz with the variables to replace in it
  1834. //
  1835. if (REG_MULTI_SZ != dwEnvType || mszEnvVars == NULL) //Bug350194, Yang Gao, 3/23/2001
  1836. {
  1837. LocalFree(szNew);
  1838. return NULL;
  1839. }
  1840. bExpanded = FALSE;
  1841. //
  1842. // Start at the beginning of the multi-sz block
  1843. //
  1844. szEnvVar = mszEnvVars;
  1845. while (*szEnvVar) {
  1846. if (UnExpandEnvironmentString(szPath,szEnvVar,szNew,cbNew)) {
  1847. //
  1848. // We can only unexpand (successfully) once
  1849. //
  1850. bExpanded = TRUE;
  1851. break;
  1852. }
  1853. //
  1854. // Advance szEnvVar to the end of this string
  1855. //
  1856. while (*szEnvVar) {
  1857. szEnvVar++;
  1858. }
  1859. //
  1860. // And the beginning of the next
  1861. //
  1862. szEnvVar++;
  1863. }
  1864. if (mszEnvVars) {
  1865. LocalFree(mszEnvVars);
  1866. }
  1867. if (!bExpanded) {
  1868. LocalFree(szNew);
  1869. szNew = NULL;
  1870. }
  1871. return szNew;
  1872. }
  1873. //+--------------------------------------------------------------------------
  1874. //
  1875. // Function: IsSystemDatabase
  1876. //
  1877. // Synopsis: Determine if a specific databse is the system database or a private one
  1878. //
  1879. // Arguments:
  1880. // [szDBPath] - The database path to check
  1881. //
  1882. // Returns: True if szDBPath is the system database, false otherwise
  1883. //
  1884. // History:
  1885. //
  1886. //---------------------------------------------------------------------------
  1887. BOOL
  1888. IsSystemDatabase(LPCTSTR szDBPath) {
  1889. CString szSysDB;
  1890. BOOL bIsSysDB;
  1891. DWORD rc;
  1892. DWORD RegType;
  1893. if (!szDBPath) {
  1894. return FALSE;
  1895. }
  1896. //Raid bug 261450, Yang Gao, 3/30/2001
  1897. if (FAILED(GetSystemDatabase(&szSysDB))) {
  1898. return FALSE;
  1899. }
  1900. //
  1901. // We found an appropriate szSysDB, so compare it with szDBPath
  1902. //
  1903. if (lstrcmp(szDBPath,szSysDB) == 0) {
  1904. bIsSysDB = TRUE;
  1905. } else {
  1906. bIsSysDB = FALSE;
  1907. }
  1908. return bIsSysDB;
  1909. }
  1910. //+--------------------------------------------------------------------------
  1911. //
  1912. // Function: GetSystemDatabase
  1913. //
  1914. // Synopsis: Get the name of the current system database
  1915. //
  1916. // Arguments:
  1917. // [szDBPath] - [in/out] a pointer for the name of the system database
  1918. // The caller is responsible for freeing it.
  1919. //
  1920. //
  1921. // Returns: S_OK if the system database is found, otherwise an error
  1922. //
  1923. // History:
  1924. //
  1925. //---------------------------------------------------------------------------
  1926. HRESULT
  1927. GetSystemDatabase(CString *szDBPath)
  1928. {
  1929. if (!szDBPath)
  1930. {
  1931. return E_INVALIDARG;
  1932. }
  1933. //Raid bug 261450, Yang Gao, 3/30/2001
  1934. CString sAppend;
  1935. sAppend.LoadString( IDS_DB_DEFAULT );
  1936. PWSTR pszPath = (LPTSTR)LocalAlloc( 0, (MAX_PATH + sAppend.GetLength() + 1) * sizeof(WCHAR));
  1937. if ( pszPath == NULL ) //Raid bug 427956, Yanggao, 7/2/2001
  1938. {
  1939. return E_FAIL;
  1940. }
  1941. if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_WINDOWS, NULL, 0, pszPath)))
  1942. {
  1943. //This is a safe usage.
  1944. wcscpy( &(pszPath[lstrlen(pszPath)]), sAppend );
  1945. *szDBPath = pszPath;
  1946. if (pszPath)
  1947. {
  1948. LocalFree(pszPath);
  1949. pszPath = NULL;
  1950. }
  1951. return S_OK;
  1952. }
  1953. if (pszPath)
  1954. {
  1955. LocalFree(pszPath);
  1956. pszPath = NULL;
  1957. }
  1958. return E_FAIL;
  1959. }
  1960. //+--------------------------------------------------------------------------
  1961. //
  1962. // Function: ObjectStatusToString
  1963. //
  1964. // Synopsis: Convert an object status value to a printable string
  1965. //
  1966. // Arguments:
  1967. // [status] - [in] The status value to convert
  1968. // [str] - [out] The string to store the value in
  1969. //
  1970. //
  1971. //---------------------------------------------------------------------------
  1972. UINT
  1973. ObjectStatusToString(DWORD status, CString *strStatus) {
  1974. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1975. if ( status & SCE_STATUS_PERMISSION_MISMATCH ) {
  1976. status = IDS_MISMATCH;
  1977. } else if (status & SCE_STATUS_AUDIT_MISMATCH) {
  1978. status = IDS_MISMATCH;
  1979. } else {
  1980. status &= 0x0F;
  1981. switch(status){
  1982. case SCE_STATUS_NOT_ANALYZED:
  1983. status = IDS_NOT_ANALYZED;
  1984. break;
  1985. case SCE_STATUS_GOOD:
  1986. status = IDS_OK ;
  1987. break;
  1988. case SCE_STATUS_MISMATCH:
  1989. status = IDS_MISMATCH;
  1990. break;
  1991. case SCE_STATUS_NOT_CONFIGURED:
  1992. //
  1993. // BUG 119215: The Analysis UI should never show "Not Defined"
  1994. // for the security of existing system objects
  1995. //
  1996. status = IDS_NOT_ANALYZED;
  1997. break;
  1998. case SCE_STATUS_CHILDREN_CONFIGURED:
  1999. status = IDS_CHILDREN_CONFIGURED;
  2000. break;
  2001. case SCE_STATUS_ERROR_NOT_AVAILABLE:
  2002. status = IDS_NOT_AVAILABLE;
  2003. break;
  2004. case SCE_STATUS_NEW_SERVICE:
  2005. status = IDS_NEW_SERVICE;
  2006. break;
  2007. default:
  2008. //
  2009. // We shouldn't get here, but for some reason we keep doing so
  2010. //
  2011. status = IDS_MISMATCH;
  2012. break;
  2013. }
  2014. }
  2015. if(strStatus){
  2016. strStatus->LoadString(status);
  2017. }
  2018. return status;
  2019. }
  2020. //+--------------------------------------------------------------------------
  2021. //
  2022. // Function: IsSecurityTemplate
  2023. //
  2024. // Synopsis: Validates a file to see if the file is a security template.
  2025. //
  2026. // Arguments: [pszFileName] - The full path to the file to check.
  2027. //
  2028. // Returns: FALSE if the file does not exist or is not a valid
  2029. // security template.
  2030. //
  2031. // TRUE if successful.
  2032. // History:
  2033. //
  2034. //---------------------------------------------------------------------------
  2035. BOOL
  2036. IsSecurityTemplate(
  2037. LPCTSTR pszFileName
  2038. )
  2039. {
  2040. if(!pszFileName){
  2041. return FALSE;
  2042. }
  2043. HANDLE hProfile;
  2044. SCESTATUS rc;
  2045. //
  2046. // Open the profile.
  2047. //
  2048. rc = SceOpenProfile(
  2049. pszFileName,
  2050. SCE_INF_FORMAT,
  2051. &hProfile
  2052. );
  2053. if(rc == SCESTATUS_SUCCESS && hProfile){
  2054. PSCE_PROFILE_INFO ProfileInfo = NULL;
  2055. PSCE_ERROR_LOG_INFO ErrBuf = NULL;
  2056. //
  2057. // The profile will be validated by trying to load all the security areas.
  2058. //
  2059. rc = SceGetSecurityProfileInfo(hProfile,
  2060. SCE_ENGINE_SCP,
  2061. AREA_ALL,
  2062. &ProfileInfo,
  2063. &ErrBuf);
  2064. if(ErrBuf){
  2065. rc = SCESTATUS_INVALID_DATA;
  2066. }
  2067. //
  2068. // Free up the memory.
  2069. //
  2070. SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO);
  2071. ErrBuf = NULL;
  2072. if ( ProfileInfo != NULL ) {
  2073. SceFreeMemory((PVOID)ProfileInfo, AREA_ALL);
  2074. LocalFree(ProfileInfo);
  2075. }
  2076. SceCloseProfile(&hProfile);
  2077. //
  2078. // return TRUE if everything is successful.
  2079. //
  2080. if(rc != SCESTATUS_INVALID_DATA){
  2081. return TRUE;
  2082. }
  2083. }
  2084. return FALSE;
  2085. }
  2086. //+--------------------------------------------------------------------------
  2087. //
  2088. // Function: WriteSprintf
  2089. //
  2090. // Synopsis: Writes formated [pszStr] to [pStm].
  2091. //
  2092. // Arguments: [pStm] - Stream to write to.
  2093. // [pszStr] - Format string to write.
  2094. // [...] - printf formating
  2095. //
  2096. // Returns: The total number of bytes written.
  2097. //
  2098. // History:
  2099. //
  2100. //---------------------------------------------------------------------------
  2101. int WriteSprintf( IStream *pStm, LPCTSTR pszStr, ...)
  2102. {
  2103. TCHAR szWrite[512];
  2104. va_list marker;
  2105. va_start(marker, pszStr);
  2106. vswprintf(szWrite, pszStr, marker);
  2107. va_end(marker);
  2108. ULONG nBytesWritten;
  2109. int iLen = lstrlen(szWrite);
  2110. if(pStm){
  2111. pStm->Write( szWrite, iLen * sizeof(TCHAR), &nBytesWritten );
  2112. return nBytesWritten;
  2113. }
  2114. return iLen;
  2115. }
  2116. //+--------------------------------------------------------------------------
  2117. //
  2118. // Function: ReadSprintf
  2119. //
  2120. // Synopsis: Reads formated [pszStr] from [pStm].
  2121. // supported character switches are
  2122. // 'd' - integer pointer.
  2123. //
  2124. // Arguments: [pStm] - Stream to read from.
  2125. // [pszStr] - Format string to test.
  2126. // [...] - pointer to the types defined by format
  2127. // specification types.
  2128. //
  2129. // Returns: Total number of bytes read from the stream
  2130. //
  2131. // History:
  2132. //
  2133. //---------------------------------------------------------------------------
  2134. int
  2135. ReadSprintf( IStream *pStm, LPCTSTR pszStr, ...)
  2136. {
  2137. if(!pStm || !pszStr){
  2138. return -1;
  2139. }
  2140. va_list marker;
  2141. va_start(marker, pszStr);
  2142. TCHAR szRead[256];
  2143. TCHAR szConv[512];
  2144. ULONG uRead = 0;
  2145. int i = 0;
  2146. LPCTSTR pszNext = szRead;
  2147. int iTotalRead = 0;
  2148. // Get the current seek position.
  2149. ULARGE_INTEGER liBack = { 0 };
  2150. LARGE_INTEGER liCur = { 0 };
  2151. pStm->Seek( liCur, STREAM_SEEK_CUR, &liBack);
  2152. #define INCBUFFER(sz)\
  2153. if(uRead){\
  2154. (sz)++;\
  2155. uRead--;\
  2156. } else {\
  2157. pStm->Read(szRead, 256 * sizeof(TCHAR), &uRead);\
  2158. uRead = uRead/sizeof(TCHAR);\
  2159. (sz) = szRead;\
  2160. }\
  2161. iTotalRead++;
  2162. while(*pszStr){
  2163. if(!uRead){
  2164. // Read information into buffer.
  2165. pStm->Read( szRead, 256 * sizeof(TCHAR), &uRead);
  2166. pszNext = szRead;
  2167. uRead = uRead/sizeof(TCHAR);
  2168. if(!uRead){
  2169. iTotalRead = -1;
  2170. break;
  2171. }
  2172. }
  2173. if(*pszStr == '%'){
  2174. pszStr++;
  2175. switch( *pszStr ){
  2176. case 'd':
  2177. // read integer.
  2178. pszStr++;
  2179. i = 0;
  2180. // copy number to our own buffer.
  2181. while( (*pszNext >= L'0' && *pszNext <= L'9') ){
  2182. szConv[i++] = *pszNext;
  2183. INCBUFFER( pszNext );
  2184. }
  2185. szConv[i] = 0;
  2186. // convert string to integer.
  2187. *(va_arg(marker, int *)) = _wtol(szConv);
  2188. continue;
  2189. case 's':
  2190. pszStr++;
  2191. i = 0;
  2192. // we have to have some kind of terminating character se we will use the
  2193. // next value in pszStr.
  2194. while( *pszNext && (*pszNext != *pszStr) ){
  2195. szConv[i++] = *pszNext;
  2196. INCBUFFER( pszNext );
  2197. }
  2198. if(*pszNext == *pszStr){
  2199. INCBUFFER( pszNext );
  2200. }
  2201. // copy the string value.
  2202. szConv[i] = 0;
  2203. if( i ){
  2204. LPTSTR pNew = (LPTSTR)LocalAlloc(0, sizeof(TCHAR) * (i + 1));
  2205. if(NULL != pNew){
  2206. //This is a safe usage.
  2207. lstrcpy(pNew, szConv);
  2208. }
  2209. LPTSTR *pArg;
  2210. pArg = (va_arg(marker, LPTSTR *));
  2211. if (pArg) {
  2212. *pArg = pNew;
  2213. }
  2214. } else {
  2215. LPTSTR *pArg = va_arg(marker, LPTSTR *); //Prefast warning 269: Incorrect order of operations: dereference ignored. Comments: It is not necessary.
  2216. }
  2217. pszStr++;
  2218. continue;
  2219. }
  2220. }
  2221. // check to make sure we are at the correct position in the file.
  2222. if(*pszStr != *pszNext){
  2223. iTotalRead = -1;
  2224. break;
  2225. }
  2226. pszStr++;
  2227. // increment buffer pointer.
  2228. INCBUFFER( pszNext );
  2229. }
  2230. va_end(marker);
  2231. // Reset streem seek pointer.
  2232. liCur.LowPart = liBack.LowPart;
  2233. if(iTotalRead >= 0){
  2234. liCur.LowPart += iTotalRead * sizeof(TCHAR);
  2235. }
  2236. liCur.HighPart = liBack.HighPart;
  2237. pStm->Seek(liCur, STREAM_SEEK_SET, NULL);
  2238. return iTotalRead;
  2239. #undef INCBUFFER
  2240. }
  2241. //+--------------------------------------------------------------------------------
  2242. // FileCreateError
  2243. //
  2244. // This function tries to create a new file use [pszFile]. It will display a
  2245. // message to the user if the file cannot be created.
  2246. //
  2247. // Arguments: [pszFile] - Full path of file to create.
  2248. // [dwFlags] - Flags
  2249. // FCE_IGNORE_FILEEXISTS - Ignore File exists error, and
  2250. // delete the file.
  2251. //
  2252. // Returns: IDYES the file can be created
  2253. // IDNo The file cannot be created
  2254. DWORD
  2255. FileCreateError(
  2256. LPCTSTR pszFile,
  2257. DWORD dwFlags
  2258. )
  2259. {
  2260. if(!pszFile){
  2261. return ERROR_INVALID_PARAMETER;
  2262. }
  2263. HANDLE hFile;
  2264. DWORD dwErr = IDNO;
  2265. //
  2266. // Try to create the file.
  2267. //
  2268. hFile = ExpandAndCreateFile(
  2269. pszFile,
  2270. GENERIC_WRITE,
  2271. 0,
  2272. NULL,
  2273. CREATE_NEW,
  2274. FILE_ATTRIBUTE_ARCHIVE,
  2275. NULL
  2276. );
  2277. if(hFile == INVALID_HANDLE_VALUE){
  2278. //
  2279. // Post error message to user.
  2280. //
  2281. dwErr = GetLastError();
  2282. LPTSTR pszErr;
  2283. CString strErr;
  2284. //This is a safe usage.
  2285. FormatMessage(
  2286. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  2287. FORMAT_MESSAGE_FROM_SYSTEM,
  2288. NULL,
  2289. dwErr,
  2290. 0,
  2291. (LPTSTR)&pszErr,
  2292. 0,
  2293. NULL
  2294. );
  2295. strErr = pszErr;
  2296. strErr += pszFile;
  2297. if(pszErr){
  2298. LocalFree(pszErr);
  2299. }
  2300. switch(dwErr){
  2301. case ERROR_ALREADY_EXISTS:
  2302. case ERROR_FILE_EXISTS:
  2303. if( dwFlags & FCE_IGNORE_FILEEXISTS ){
  2304. dwErr = IDYES;
  2305. break;
  2306. }
  2307. //
  2308. // Confirm overwrite.
  2309. //
  2310. strErr.Format(IDS_FILE_EXISTS_FMT, pszFile);
  2311. dwErr = AfxMessageBox(
  2312. strErr,
  2313. MB_YESNO
  2314. );
  2315. break;
  2316. default:
  2317. //
  2318. // The file cannot be created.
  2319. //
  2320. AfxMessageBox(
  2321. strErr,
  2322. MB_OK
  2323. );
  2324. dwErr = IDNO;
  2325. break;
  2326. }
  2327. } else {
  2328. //
  2329. // It's OK to create the file.
  2330. //
  2331. ::CloseHandle( hFile );
  2332. DeleteFile(pszFile);
  2333. dwErr = IDYES;
  2334. }
  2335. return dwErr;
  2336. }
  2337. //+--------------------------------------------------------------------------
  2338. //
  2339. // Function: IsDBCSPath
  2340. //
  2341. // Synopsis: Check if a path contains DBCS characters
  2342. //
  2343. // Arguments: [pszFile] - [in] The path to check
  2344. //
  2345. // Returns: TRUE if pszFile contains characters that can't be
  2346. // represented by a LPSTR
  2347. //
  2348. // FALSE if pszFile only contains characters that can
  2349. // be represented by a LPSTR
  2350. //
  2351. //
  2352. //+--------------------------------------------------------------------------
  2353. BOOL
  2354. IsDBCSPath(LPCTSTR szWideFile) {
  2355. while(*szWideFile) {
  2356. if (*szWideFile >= 256) {
  2357. return TRUE;
  2358. }
  2359. szWideFile++;
  2360. }
  2361. return FALSE;
  2362. /*
  2363. LPSTR szMBFile;
  2364. int nMBFile;
  2365. BOOL bUsedDefaultChar = FALSE;
  2366. nMBFile = sizeof(LPSTR)*(lstrlen(szWideFile));
  2367. szMBFile = (LPSTR)LocalAlloc(LPTR,nMBFile+1);
  2368. if (szMBFile) {
  2369. WideCharToMultiByte( CP_ACP,
  2370. 0,
  2371. szWideFile,
  2372. -1,
  2373. szMBFile,
  2374. nMBFile,
  2375. NULL,
  2376. &bUsedDefaultChar);
  2377. LocalFree(szMBFile);
  2378. }
  2379. return bUsedDefaultChar;
  2380. */
  2381. }
  2382. //+--------------------------------------------------------------------------
  2383. //
  2384. // Function: GetSeceditHelpFilename
  2385. //
  2386. // Synopsis: Return the fully qualified path the help file for Secedit
  2387. //
  2388. // Arguments: None
  2389. //
  2390. // Returns: a CString containing the fully qualified help file name.
  2391. //
  2392. //
  2393. //+--------------------------------------------------------------------------
  2394. CString GetSeceditHelpFilename()
  2395. {
  2396. static CString helpFileName;
  2397. if ( helpFileName.IsEmpty () )
  2398. {
  2399. UINT result = ::GetSystemWindowsDirectory (
  2400. helpFileName.GetBufferSetLength (MAX_PATH+1), MAX_PATH);
  2401. ASSERT(result != 0 && result <= MAX_PATH); //Bogus assert. Yanggao.
  2402. helpFileName.ReleaseBuffer ();
  2403. helpFileName += L"\\help\\wsecedit.hlp";
  2404. }
  2405. return helpFileName;
  2406. }
  2407. //+--------------------------------------------------------------------------
  2408. //
  2409. // Function: GetGpeditHelpFilename
  2410. //
  2411. // Synopsis: Return the fully qualified path the help file for Secedit
  2412. //
  2413. // Arguments: None
  2414. //
  2415. // Returns: a CString containing the fully qualified help file name.
  2416. //
  2417. //
  2418. //+--------------------------------------------------------------------------
  2419. CString GetGpeditHelpFilename()
  2420. {
  2421. static CString helpFileName;
  2422. if ( helpFileName.IsEmpty () )
  2423. {
  2424. UINT result = ::GetSystemWindowsDirectory (
  2425. helpFileName.GetBufferSetLength (MAX_PATH+1), MAX_PATH);
  2426. ASSERT(result != 0 && result <= MAX_PATH); //Bogus Assert. Yanggao.
  2427. helpFileName.ReleaseBuffer ();
  2428. helpFileName += L"\\help\\gpedit.hlp";
  2429. }
  2430. return helpFileName;
  2431. }
  2432. //+--------------------------------------------------------------------------
  2433. //
  2434. // Function: ExpandEnvironmentStringWrapper
  2435. //
  2436. // Synopsis: Takes an LPTSTR and expands the enviroment variables in it
  2437. //
  2438. // Arguments: Pointer to the string to expand.
  2439. //
  2440. // Returns: a CString containing the fully expanded string.
  2441. //
  2442. //+--------------------------------------------------------------------------
  2443. CString ExpandEnvironmentStringWrapper(LPCTSTR psz)
  2444. {
  2445. LPTSTR pszBuffer = NULL;
  2446. DWORD dwExpanded = 0;
  2447. CString sz;
  2448. dwExpanded = ExpandEnvironmentStrings(psz, NULL, 0);
  2449. pszBuffer = sz.GetBuffer(dwExpanded);
  2450. ExpandEnvironmentStrings(psz, pszBuffer, dwExpanded);
  2451. sz.ReleaseBuffer();
  2452. return (sz);
  2453. }
  2454. //+--------------------------------------------------------------------------
  2455. //
  2456. // Function: ExpandAndCreateFile
  2457. //
  2458. // Synopsis: Just does a normal CreateFile(), but expands the filename before
  2459. // creating the file.
  2460. //
  2461. // Arguments: Same as CreateFile().
  2462. //
  2463. // Returns: HANDLE to the created file.
  2464. //
  2465. //+--------------------------------------------------------------------------
  2466. HANDLE WINAPI ExpandAndCreateFile (
  2467. LPCTSTR lpFileName,
  2468. DWORD dwDesiredAccess,
  2469. DWORD dwShareMode,
  2470. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  2471. DWORD dwCreationDisposition,
  2472. DWORD dwFlagsAndAttributes,
  2473. HANDLE hTemplateFile
  2474. )
  2475. {
  2476. HANDLE hRet = INVALID_HANDLE_VALUE;
  2477. CString sz;
  2478. sz = ExpandEnvironmentStringWrapper(lpFileName);
  2479. //This is a safe usage. sz is full path.
  2480. return (CreateFile(
  2481. sz,
  2482. dwDesiredAccess,
  2483. dwShareMode,
  2484. lpSecurityAttributes,
  2485. dwCreationDisposition,
  2486. dwFlagsAndAttributes,
  2487. hTemplateFile));
  2488. }
  2489. //**********************************************************************
  2490. //
  2491. // FUNCTION: IsAdmin - This function checks the token of the
  2492. // calling thread to see if the caller belongs to
  2493. // the Administrators group.
  2494. //
  2495. // PARAMETERS: none
  2496. //
  2497. // RETURN VALUE: TRUE if the caller is an administrator on the local
  2498. // machine. Otherwise, FALSE.
  2499. //
  2500. //**********************************************************************
  2501. BOOL IsAdmin(void) {
  2502. HANDLE hAccessToken = NULL;
  2503. PTOKEN_GROUPS ptgGroups = NULL;
  2504. DWORD cbGroups = 0;
  2505. PSID psidAdmin = NULL;
  2506. UINT i;
  2507. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  2508. // assume the caller is not an administrator
  2509. BOOL bIsAdmin = FALSE;
  2510. __try {
  2511. if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,
  2512. &hAccessToken)) {
  2513. if (GetLastError() != ERROR_NO_TOKEN)
  2514. __leave;
  2515. // retry against process token if no thread token exists
  2516. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
  2517. &hAccessToken))
  2518. __leave;
  2519. }
  2520. // determine required size of buffer for token information
  2521. if (GetTokenInformation(hAccessToken, TokenGroups, NULL, 0,
  2522. &cbGroups)) {
  2523. // call should have failed due to zero-length buffer
  2524. __leave;
  2525. } else {
  2526. // call should have failed due to zero-length buffer
  2527. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  2528. __leave;
  2529. }
  2530. // allocate a buffer to hold the token groups
  2531. ptgGroups = (PTOKEN_GROUPS) HeapAlloc(GetProcessHeap(), 0,
  2532. cbGroups);
  2533. if (!ptgGroups)
  2534. __leave;
  2535. // call GetTokenInformation() again to actually retrieve the groups
  2536. if (!GetTokenInformation(hAccessToken, TokenGroups, ptgGroups,
  2537. cbGroups, &cbGroups))
  2538. __leave;
  2539. // create a SID for the local administrators group
  2540. // This is a safe usage.
  2541. if (!AllocateAndInitializeSid(&siaNtAuthority, 2,
  2542. SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
  2543. 0, 0, 0, 0, 0, 0, &psidAdmin))
  2544. __leave;
  2545. // scan the token's groups and compare the SIDs to the admin SID
  2546. for (i = 0; i < ptgGroups->GroupCount; i++) {
  2547. //This is a safe usage. psidAdmin is a local admin SID.
  2548. if (EqualSid(psidAdmin, ptgGroups->Groups[i].Sid)) {
  2549. bIsAdmin = TRUE;
  2550. break;
  2551. }
  2552. }
  2553. } __finally {
  2554. // free resources
  2555. if (hAccessToken)
  2556. CloseHandle(hAccessToken);
  2557. if (ptgGroups)
  2558. HeapFree(GetProcessHeap(), 0, ptgGroups);
  2559. if (psidAdmin)
  2560. FreeSid(psidAdmin);
  2561. }
  2562. return bIsAdmin;
  2563. }
  2564. //+--------------------------------------------------------------------------
  2565. //
  2566. // Function: MultiSZToSZ
  2567. //
  2568. // Synopsis: Converts a multiline string to a comma delimited normal string
  2569. //
  2570. // Returns: The converted string
  2571. //
  2572. //+--------------------------------------------------------------------------
  2573. PWSTR MultiSZToSZ(PCWSTR sz)
  2574. {
  2575. PWSTR szOut = NULL;
  2576. ASSERT(sz);
  2577. if (!sz)
  2578. {
  2579. return NULL;
  2580. }
  2581. //Bug 349000, Yang Gao, 3/23/2001
  2582. long i = 0;
  2583. long j = 0;
  2584. while( L'\0' != sz[i] )
  2585. {
  2586. if( L',' == sz[i] )
  2587. j++;
  2588. i++;
  2589. }
  2590. szOut = (PWSTR) LocalAlloc(LPTR,(lstrlen(sz)+j*2+1)*sizeof(wchar_t)); //Raid #376228, 4/25/2001
  2591. if (!szOut)
  2592. {
  2593. return NULL;
  2594. }
  2595. BOOL newline = FALSE; //raid #464335, Yang Gao, 9/7/2001
  2596. for(i=0,j=0; sz[i] != L'\0'; i++)
  2597. {
  2598. if( L'\n' == sz[i] )
  2599. {
  2600. if( newline )
  2601. {
  2602. szOut[j++] = MULTISZ_DELIMITER;
  2603. }
  2604. newline = FALSE;
  2605. continue;
  2606. }
  2607. if( L'\r' == sz[i] )
  2608. {
  2609. continue; // ignore it
  2610. }
  2611. if( L' ' == sz[i] && !newline ) //raid #464335, Yang Gao, 9/7/2001
  2612. {
  2613. continue; //delete it if it occurs before any char of each line.
  2614. }
  2615. newline = TRUE;
  2616. if( L',' == sz[i] )
  2617. {
  2618. szOut[j++] = MULTISZ_QUOTE;
  2619. szOut[j++] = sz[i];
  2620. szOut[j++] = MULTISZ_QUOTE;
  2621. continue;
  2622. }
  2623. szOut[j++] = sz[i];
  2624. }
  2625. return szOut;
  2626. }
  2627. //+--------------------------------------------------------------------------
  2628. //
  2629. // Function: SZToMultiSZ
  2630. //
  2631. // Synopsis: Converts a comma delimited string to a multiline string
  2632. //
  2633. // Returns: The converted string
  2634. //
  2635. //+--------------------------------------------------------------------------
  2636. PWSTR SZToMultiSZ(PCWSTR sz)
  2637. {
  2638. PWSTR szOut = NULL;
  2639. ASSERT(sz);
  2640. if (!sz)
  2641. {
  2642. return NULL;
  2643. }
  2644. //
  2645. // Calculate the length of the expanded string
  2646. //
  2647. int cSZ = 0;
  2648. for (int i = 0;sz[i] != L'\0'; i++)
  2649. {
  2650. if (MULTISZ_DELIMITER == sz[i])
  2651. {
  2652. //
  2653. // Delimiter expands into an extra character so count it twice
  2654. //
  2655. cSZ++;
  2656. }
  2657. cSZ++;
  2658. }
  2659. szOut = (PWSTR) LocalAlloc(LPTR,(cSZ+1)*sizeof(wchar_t));
  2660. if (!szOut)
  2661. {
  2662. return NULL;
  2663. }
  2664. BOOL qflag = FALSE;
  2665. for(int i=0, c=0; sz[i] != L'\0'; i++)
  2666. {
  2667. //Bug 349000, Yang Gao, 3/23/2001
  2668. if( MULTISZ_QUOTE == sz[i] && MULTISZ_DELIMITER == sz[i+1] )
  2669. {
  2670. qflag = TRUE;
  2671. continue;
  2672. }
  2673. if( MULTISZ_DELIMITER == sz[i] && MULTISZ_QUOTE == sz[i+1] && qflag )
  2674. {
  2675. szOut[c++] = sz[i];
  2676. i++;
  2677. qflag = FALSE;
  2678. continue;
  2679. }
  2680. qflag = FALSE;
  2681. if (MULTISZ_DELIMITER == sz[i])
  2682. {
  2683. szOut[c++] = L'\r';
  2684. szOut[c++] = L'\n';
  2685. }
  2686. else
  2687. {
  2688. szOut[c++] = sz[i];
  2689. }
  2690. }
  2691. return szOut;
  2692. }
  2693. //+--------------------------------------------------------------------------
  2694. //
  2695. // Function: MultiSZToDisp
  2696. //
  2697. // Synopsis: Converts a comma delimited multiline string to a display string
  2698. //
  2699. // Returns: The converted string
  2700. // Bug 349000, Yang Gao, 3/23/2001
  2701. //+--------------------------------------------------------------------------
  2702. void MultiSZToDisp(PCWSTR sz, CString &pszOut)
  2703. {
  2704. ASSERT(sz);
  2705. if (!sz)
  2706. {
  2707. return;
  2708. }
  2709. //
  2710. // Calculate the length of the expanded string
  2711. //
  2712. int cSZ = 0;
  2713. for (int i = 0;sz[i] != L'\0'; i++)
  2714. {
  2715. if (MULTISZ_DELIMITER == sz[i])
  2716. {
  2717. //
  2718. // Delimiter expands into an extra character so count it twice
  2719. //
  2720. cSZ++;
  2721. }
  2722. cSZ++;
  2723. }
  2724. PWSTR szOut;
  2725. szOut = (PWSTR) LocalAlloc(LPTR,(cSZ+1)*sizeof(wchar_t));
  2726. if (!szOut)
  2727. {
  2728. return;
  2729. }
  2730. BOOL qflag = FALSE;
  2731. for(int i=0, c=0; sz[i] != L'\0'; i++)
  2732. {
  2733. if( MULTISZ_QUOTE == sz[i] && MULTISZ_DELIMITER == sz[i+1] )
  2734. {
  2735. qflag = TRUE;
  2736. continue;
  2737. }
  2738. if( MULTISZ_DELIMITER == sz[i] && MULTISZ_QUOTE == sz[i+1] && qflag )
  2739. {
  2740. szOut[c++] = sz[i];
  2741. i++;
  2742. qflag = FALSE;
  2743. continue;
  2744. }
  2745. qflag = FALSE;
  2746. szOut[c++] = sz[i];
  2747. }
  2748. pszOut = szOut;
  2749. LocalFree(szOut);
  2750. return;
  2751. }
  2752. SCE_PROFILE_INFO *g_pDefaultTemplate = NULL;
  2753. SCE_PROFILE_INFO *
  2754. GetDefaultTemplate() {
  2755. SCE_PROFILE_INFO *pspi = NULL;
  2756. DWORD RegType = 0;
  2757. SCESTATUS rc = 0;
  2758. LPTSTR szInfFile = NULL;
  2759. PVOID pHandle = NULL;
  2760. if (g_pDefaultTemplate) {
  2761. return g_pDefaultTemplate;
  2762. }
  2763. rc = MyRegQueryValue(HKEY_LOCAL_MACHINE,
  2764. SCE_REGISTRY_KEY,
  2765. SCE_REGISTRY_DEFAULT_TEMPLATE,
  2766. (PVOID *)&szInfFile,
  2767. &RegType );
  2768. if (ERROR_SUCCESS != rc) {
  2769. if (szInfFile) {
  2770. LocalFree(szInfFile);
  2771. szInfFile = NULL;
  2772. }
  2773. return NULL;
  2774. }
  2775. if (EngineOpenProfile(szInfFile,OPEN_PROFILE_CONFIGURE,&pHandle) != SCESTATUS_SUCCESS) {
  2776. LocalFree(szInfFile);
  2777. szInfFile = NULL;
  2778. return NULL;
  2779. }
  2780. LocalFree(szInfFile);
  2781. szInfFile = NULL;
  2782. rc = SceGetSecurityProfileInfo(pHandle,
  2783. SCE_ENGINE_SCP,
  2784. AREA_ALL,
  2785. &pspi,
  2786. NULL
  2787. );
  2788. SceCloseProfile(&pHandle);
  2789. if (SCESTATUS_SUCCESS != rc) {
  2790. //
  2791. // expand registry value section based on registry values list on local machine
  2792. //
  2793. SceRegEnumAllValues(
  2794. &(pspi->RegValueCount),
  2795. &(pspi->aRegValues)
  2796. );
  2797. #define PD(X,Y) if (pspi->X == SCE_NO_VALUE) { pspi->X = Y; }
  2798. PD(MaximumPasswordAge,MAX_PASS_AGE_DEFAULT)
  2799. PD(MinimumPasswordAge,MIN_PASS_AGE_DEFAULT)
  2800. PD(MinimumPasswordLength,MIN_PASS_LENGTH_DEFAULT)
  2801. PD(PasswordHistorySize,PASS_HISTORY_SIZE_DEFAULT)
  2802. PD(PasswordComplexity,PASS_COMPLEXITY_DEFAULT)
  2803. PD(RequireLogonToChangePassword,REQUIRE_LOGIN_DEFAULT)
  2804. PD(LockoutBadCount,LOCKOUT_BAD_COUNT_DEFAULT)
  2805. PD(ResetLockoutCount,RESET_LOCKOUT_COUNT_DEFAULT)
  2806. PD(LockoutDuration,LOCKOUT_DURATION_DEFAULT)
  2807. PD(AuditSystemEvents,AUDIT_SYSTEM_EVENTS_DEFAULT)
  2808. PD(AuditLogonEvents,AUDIT_LOGON_EVENTS_DEFAULT)
  2809. PD(AuditObjectAccess,AUDIT_OBJECT_ACCESS_DEFAULT)
  2810. PD(AuditPrivilegeUse,AUDIT_PRIVILEGE_USE_DEFAULT)
  2811. PD(AuditPolicyChange,AUDIT_POLICY_CHANGE_DEFAULT)
  2812. PD(AuditAccountManage,AUDIT_ACCOUNT_MANAGE_DEFAULT)
  2813. PD(AuditProcessTracking,AUDIT_PROCESS_TRACKING_DEFAULT)
  2814. PD(AuditDSAccess,AUDIT_DS_ACCESS_DEFAULT)
  2815. PD(AuditAccountLogon,AUDIT_ACCOUNT_LOGON_DEFAULT)
  2816. PD(ForceLogoffWhenHourExpire,FORCE_LOGOFF_DEFAULT)
  2817. PD(EnableAdminAccount,ENABLE_ADMIN_DEFAULT)
  2818. PD(EnableGuestAccount,ENABLE_GUEST_DEFAULT)
  2819. PD(LSAAnonymousNameLookup,LSA_ANON_LOOKUP_DEFAULT)
  2820. PD(MaximumLogSize[EVENT_TYPE_SYSTEM],SYS_MAX_LOG_SIZE_DEFAULT)
  2821. PD(MaximumLogSize[EVENT_TYPE_APP],APP_MAX_LOG_SIZE_DEFAULT)
  2822. PD(MaximumLogSize[EVENT_TYPE_SECURITY],SEC_MAX_LOG_SIZE_DEFAULT)
  2823. PD(AuditLogRetentionPeriod[EVENT_TYPE_SYSTEM],SYS_LOG_RETENTION_PERIOD_DEFAULT)
  2824. PD(AuditLogRetentionPeriod[EVENT_TYPE_APP],APP_LOG_RETENTION_PERIOD_DEFAULT)
  2825. PD(AuditLogRetentionPeriod[EVENT_TYPE_SECURITY],SEC_LOG_RETENTION_PERIOD_DEFAULT)
  2826. PD(RetentionDays[EVENT_TYPE_APP],APP_LOG_RETENTION_DAYS_DEFAULT)
  2827. PD(RetentionDays[EVENT_TYPE_SYSTEM],SYS_LOG_RETENTION_DAYS_DEFAULT)
  2828. PD(RetentionDays[EVENT_TYPE_SECURITY],SEC_LOG_RETENTION_DAYS_DEFAULT)
  2829. PD(RestrictGuestAccess[EVENT_TYPE_APP],APP_RESTRICT_GUEST_ACCESS_DEFAULT)
  2830. PD(RestrictGuestAccess[EVENT_TYPE_SYSTEM],SYS_RESTRICT_GUEST_ACCESS_DEFAULT)
  2831. PD(RestrictGuestAccess[EVENT_TYPE_SECURITY],SEC_RESTRICT_GUEST_ACCESS_DEFAULT)
  2832. if (pspi->pFiles.pAllNodes->Count == 0) {
  2833. DWORD SDSize = 0;
  2834. pspi->pFiles.pAllNodes->Count = 1;
  2835. pspi->pFiles.pAllNodes->pObjectArray[0] =
  2836. (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR,sizeof(SCE_OBJECT_SECURITY));
  2837. if (pspi->pFiles.pAllNodes->pObjectArray[0]) {
  2838. SceSvcConvertTextToSD (
  2839. FILE_SYSTEM_SECURITY_DEFAULT,
  2840. &(pspi->pFiles.pAllNodes->pObjectArray[0]->pSecurityDescriptor),
  2841. &SDSize,
  2842. &(pspi->pFiles.pAllNodes->pObjectArray[0]->SeInfo)
  2843. );
  2844. }
  2845. }
  2846. if (pspi->pRegistryKeys.pAllNodes->Count == 0) {
  2847. DWORD SDSize = 0;
  2848. pspi->pRegistryKeys.pAllNodes->Count = 1;
  2849. pspi->pRegistryKeys.pAllNodes->pObjectArray[0] =
  2850. (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR,sizeof(SCE_OBJECT_SECURITY));
  2851. if (pspi->pRegistryKeys.pAllNodes->pObjectArray[0]) {
  2852. SceSvcConvertTextToSD (
  2853. REGISTRY_SECURITY_DEFAULT,
  2854. &(pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->pSecurityDescriptor),
  2855. &SDSize,
  2856. &(pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->SeInfo)
  2857. );
  2858. }
  2859. }
  2860. if (pspi->pServices->General.pSecurityDescriptor == NULL) {
  2861. DWORD SDSize = 0;
  2862. SceSvcConvertTextToSD (
  2863. SERVICE_SECURITY_DEFAULT,
  2864. &(pspi->pServices->General.pSecurityDescriptor),
  2865. &SDSize,
  2866. &(pspi->pServices->SeInfo)
  2867. );
  2868. }
  2869. }
  2870. g_pDefaultTemplate = pspi;
  2871. return pspi;
  2872. }
  2873. HRESULT
  2874. GetDefaultFileSecurity(PSECURITY_DESCRIPTOR *ppSD,
  2875. SECURITY_INFORMATION *pSeInfo) {
  2876. SCE_PROFILE_INFO *pspi = NULL;
  2877. ASSERT(ppSD);
  2878. ASSERT(pSeInfo);
  2879. if (!ppSD || !pSeInfo) {
  2880. return E_INVALIDARG;
  2881. }
  2882. pspi = GetDefaultTemplate();
  2883. *ppSD = NULL;
  2884. *pSeInfo = 0;
  2885. if (!pspi) {
  2886. return E_FAIL;
  2887. }
  2888. if (!pspi->pFiles.pAllNodes) {
  2889. return E_FAIL;
  2890. }
  2891. if (pspi->pFiles.pAllNodes->Count == 0) {
  2892. return E_FAIL;
  2893. }
  2894. *pSeInfo = pspi->pFiles.pAllNodes->pObjectArray[0]->SeInfo;
  2895. return MyMakeSelfRelativeSD(pspi->pFiles.pAllNodes->pObjectArray[0]->pSecurityDescriptor,
  2896. ppSD);
  2897. }
  2898. HRESULT
  2899. GetDefaultRegKeySecurity(PSECURITY_DESCRIPTOR *ppSD,
  2900. SECURITY_INFORMATION *pSeInfo) {
  2901. SCE_PROFILE_INFO *pspi = NULL;
  2902. ASSERT(ppSD);
  2903. ASSERT(pSeInfo);
  2904. if (!ppSD || !pSeInfo) {
  2905. return E_INVALIDARG;
  2906. }
  2907. pspi = GetDefaultTemplate();
  2908. *ppSD = NULL;
  2909. *pSeInfo = 0;
  2910. if (!pspi) {
  2911. return E_FAIL;
  2912. }
  2913. if (!pspi->pRegistryKeys.pAllNodes) {
  2914. return E_FAIL;
  2915. }
  2916. if (pspi->pRegistryKeys.pAllNodes->Count == 0) {
  2917. return E_FAIL;
  2918. }
  2919. *pSeInfo = pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->SeInfo;
  2920. return MyMakeSelfRelativeSD(pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->pSecurityDescriptor,
  2921. ppSD);
  2922. }
  2923. HRESULT
  2924. GetDefaultServiceSecurity(PSECURITY_DESCRIPTOR *ppSD,
  2925. SECURITY_INFORMATION *pSeInfo) {
  2926. SCE_PROFILE_INFO *pspi = NULL;
  2927. ASSERT(ppSD);
  2928. ASSERT(pSeInfo);
  2929. if (!ppSD || !pSeInfo) {
  2930. return E_INVALIDARG;
  2931. }
  2932. pspi = GetDefaultTemplate();
  2933. *ppSD = NULL;
  2934. *pSeInfo = 0;
  2935. if (!pspi) {
  2936. return E_FAIL;
  2937. }
  2938. if (!pspi->pServices) {
  2939. return E_FAIL;
  2940. }
  2941. *pSeInfo = pspi->pServices->SeInfo;
  2942. return MyMakeSelfRelativeSD(pspi->pServices->General.pSecurityDescriptor,
  2943. ppSD);
  2944. }
  2945. BOOL
  2946. GetSecureWizardName(
  2947. OUT LPTSTR *ppstrPathName OPTIONAL,
  2948. OUT LPTSTR *ppstrDisplayName OPTIONAL
  2949. )
  2950. {
  2951. BOOL b=FALSE;
  2952. if ( ppstrPathName == NULL && ppstrDisplayName == NULL) return FALSE;
  2953. if ( ppstrPathName )
  2954. *ppstrPathName = NULL;
  2955. if ( ppstrDisplayName )
  2956. *ppstrDisplayName = NULL;
  2957. #define SCE_WIZARD_PATH SCE_ROOT_PATH TEXT("\\Wizard")
  2958. DWORD rc;
  2959. DWORD RegType;
  2960. LPVOID pValue=NULL;
  2961. PWSTR pPathName = NULL;
  2962. rc = MyRegQueryValue(HKEY_LOCAL_MACHINE,
  2963. SCE_WIZARD_PATH,
  2964. TEXT("Path"),
  2965. &pValue,
  2966. &RegType
  2967. );
  2968. if ( ERROR_SUCCESS == rc && pValue &&
  2969. (RegType == REG_SZ ||
  2970. RegType == REG_EXPAND_SZ) ) {
  2971. if ( RegType == REG_EXPAND_SZ ) {
  2972. //
  2973. // Expand the environment variable
  2974. //
  2975. DWORD dSize = ExpandEnvironmentStrings((LPTSTR)pValue, NULL, 0);
  2976. if ( dSize > 0 ) {
  2977. pPathName = (PWSTR)LocalAlloc(LPTR, (dSize+1)*sizeof(WCHAR));
  2978. if ( pPathName ) {
  2979. ExpandEnvironmentStrings((LPTSTR)pValue, pPathName, dSize);
  2980. } else {
  2981. LocalFree(pValue);
  2982. return FALSE;
  2983. }
  2984. } else {
  2985. LocalFree(pValue);
  2986. return FALSE;
  2987. }
  2988. } else {
  2989. //
  2990. // just simply take the string
  2991. //
  2992. pPathName = (LPTSTR)pValue;
  2993. pValue = NULL;
  2994. }
  2995. if ( ppstrDisplayName ) {
  2996. //
  2997. // now query the display name (menu name) from the binary
  2998. // binary name is stored in pPathName (can't be NULL)
  2999. //
  3000. DWORD dwHandle=0;
  3001. DWORD dwSize = GetFileVersionInfoSize(pPathName, &dwHandle);
  3002. if ( dwSize > 0 ) {
  3003. LPVOID pBuffer = (LPVOID)LocalAlloc(LPTR, dwSize+1);
  3004. if ( pBuffer ) {
  3005. if ( GetFileVersionInfo(pPathName, 0, dwSize, pBuffer) ) {
  3006. PVOID lpInfo = 0;
  3007. UINT cch = 0;
  3008. CString key;
  3009. WCHAR szBuffer[10];
  3010. CString keyBase;
  3011. //This is a safe usage.
  3012. wsprintf (szBuffer, L"%04X", GetUserDefaultLangID ());
  3013. wcscat (szBuffer, L"04B0");
  3014. keyBase = L"\\StringFileInfo\\";
  3015. keyBase += szBuffer;
  3016. keyBase += L"\\";
  3017. key = keyBase + L"FileDescription";
  3018. if ( VerQueryValue (pBuffer, const_cast <PWSTR>((PCWSTR) key), &lpInfo, &cch) ) {
  3019. *ppstrDisplayName = (PWSTR)LocalAlloc(LPTR,(cch+1)*sizeof(WCHAR));
  3020. if ( *ppstrDisplayName ) {
  3021. //This may not be a safe usage. ppstrDisplayName is PTSTR. Consider fix.
  3022. wcscpy(*ppstrDisplayName, (PWSTR)lpInfo);
  3023. b=TRUE;
  3024. }
  3025. }
  3026. }
  3027. LocalFree(pBuffer);
  3028. }
  3029. }
  3030. }
  3031. //
  3032. // get the binary name
  3033. //
  3034. if ( ppstrPathName ) {
  3035. *ppstrPathName = pPathName;
  3036. pPathName = NULL;
  3037. b=TRUE;
  3038. }
  3039. }
  3040. if ( pPathName && (pPathName != pValue ) ) {
  3041. LocalFree(pPathName);
  3042. }
  3043. if ( pValue ) {
  3044. LocalFree(pValue);
  3045. }
  3046. return b;
  3047. }
  3048. BOOL IsValidFileName(CString& str)
  3049. {
  3050. CString text;
  3051. CString charsWithSpaces;
  3052. UINT nIndex = 0;
  3053. PCWSTR szInvalidCharSet = ILLEGAL_FILENAME_CHARS;
  3054. if( str == L'.' || str == L"..") //Raid #617915, Yanggao
  3055. return FALSE;
  3056. if( -1 != str.FindOneOf(szInvalidCharSet) )
  3057. {
  3058. while (szInvalidCharSet[nIndex])
  3059. {
  3060. charsWithSpaces += szInvalidCharSet[nIndex];
  3061. charsWithSpaces += L" ";
  3062. nIndex++;
  3063. }
  3064. //This is a sage usage.
  3065. text.FormatMessage (IDS_INVALID_FILENAME, charsWithSpaces);
  3066. AfxMessageBox(text, MB_OK|MB_ICONEXCLAMATION);
  3067. return FALSE;
  3068. }
  3069. //Raid 484084, Yanggao, 10/24/2001
  3070. int strlength = str.GetLength();
  3071. if( 1==strlength && (str.GetAt(0) == L'/' || str.GetAt(0) == L'\\') )
  3072. {
  3073. szInvalidCharSet = ILLEGAL_FILENAME_CHARS2; //Raid #526397, 2/26/2002, yanggao
  3074. while (szInvalidCharSet[nIndex])
  3075. {
  3076. charsWithSpaces += szInvalidCharSet[nIndex];
  3077. charsWithSpaces += L" ";
  3078. nIndex++;
  3079. }
  3080. //This is a safe usage.
  3081. text.FormatMessage (IDS_INVALID_FILENAMEPATH, charsWithSpaces);
  3082. AfxMessageBox(text, MB_OK|MB_ICONEXCLAMATION);
  3083. return FALSE;
  3084. }
  3085. int pos1 = str.Find(L"\\\\");
  3086. int pos2 = str.Find(L"//");
  3087. int pos3 = str.Find(L"\\/");
  3088. int pos4 = str.Find(L"/\\");
  3089. if( pos1>=0 || pos2>=0 || pos3>=0 || pos4>=0 ) //Raid #498480, yanggao, do not accept "\\".
  3090. {
  3091. szInvalidCharSet = ILLEGAL_FILENAME_CHARS1;
  3092. while (szInvalidCharSet[nIndex])
  3093. {
  3094. charsWithSpaces += szInvalidCharSet[nIndex];
  3095. charsWithSpaces += L" ";
  3096. nIndex++;
  3097. }
  3098. //This is a safe usage.
  3099. text.FormatMessage (IDS_INVALID_FILENAME, charsWithSpaces);
  3100. AfxMessageBox(text, MB_OK|MB_ICONEXCLAMATION);
  3101. return FALSE;
  3102. }
  3103. return TRUE;
  3104. }
  3105. ///////////////////////////////////////////////////////////////////
  3106. //Raid #533432, yanggao, 4/3/2002
  3107. //Currently pextension should include '.'
  3108. ///////////////////////////////////////////////////////////////////
  3109. #define IsDigit(c) ((c) >= L'0' && c <= L'9')
  3110. BOOL IsNameReserved(LPCWSTR pszName, LPCWSTR pextension)
  3111. {
  3112. static const WCHAR *rgszPorts3[] = {
  3113. TEXT("NUL"),
  3114. TEXT("PRN"),
  3115. TEXT("CON"),
  3116. TEXT("AUX"),
  3117. };
  3118. static const WCHAR *rgszPorts4[] = {
  3119. TEXT("LPT"), // LPT#
  3120. TEXT("COM"), // COM#
  3121. };
  3122. if( !pszName || !pextension )
  3123. return FALSE;
  3124. CString sz = pszName;
  3125. CString tempsz = pextension;
  3126. if( _wcsicmp(sz.Right(tempsz.GetLength()), tempsz) == 0 ) //Remove extension
  3127. {
  3128. tempsz = sz.Left(sz.GetLength() - tempsz.GetLength());
  3129. }
  3130. else
  3131. {
  3132. tempsz = sz;
  3133. }
  3134. int cch = tempsz.ReverseFind(L'\\'); //Remove path
  3135. int iMax = tempsz.ReverseFind(L'/');
  3136. if( cch < iMax )
  3137. {
  3138. cch = iMax;
  3139. }
  3140. if( cch >= 0 )
  3141. {
  3142. cch = tempsz.GetLength() - cch - 1;
  3143. sz = tempsz.Right(cch);
  3144. }
  3145. else
  3146. {
  3147. sz = tempsz;
  3148. }
  3149. LPCTSTR* rgszPorts = rgszPorts3;
  3150. cch = sz.GetLength();
  3151. tempsz = sz;
  3152. iMax = ARRAYSIZE(rgszPorts3);
  3153. if (cch == 4 && IsDigit(sz.GetAt(3)))
  3154. {
  3155. // if 4 chars start with LPT checks
  3156. // need to filter out:
  3157. // COM1, COM2, etc. LPT1, LPT2, etc
  3158. // but not:
  3159. // COM or LPT or LPT10 or COM10
  3160. // COM == 1 and LPT == 0
  3161. iMax = ARRAYSIZE(rgszPorts4);
  3162. rgszPorts = rgszPorts4;
  3163. sz.SetAt(3, L'\0');
  3164. cch = 3;
  3165. }
  3166. if (cch == 3)
  3167. {
  3168. int i = 0;
  3169. for (i; i < iMax; i++)
  3170. {
  3171. if (!lstrcmpi(rgszPorts[i], sz))
  3172. {
  3173. break;
  3174. }
  3175. }
  3176. if( i != iMax )
  3177. {
  3178. sz.FormatMessage(IDS_RESERVED_NAME, tempsz);
  3179. AfxMessageBox(sz, MB_OK|MB_ICONEXCLAMATION);
  3180. return TRUE;
  3181. }
  3182. }
  3183. return FALSE;
  3184. }