Source code of Windows XP (NT5)
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.

894 lines
23 KiB

  1. /*++
  2. Copyright (c) 1998 - 1998 Microsoft Corporation
  3. Module Name: utils.cpp
  4. Abstract: This Module implements the utility routines for dsacls
  5. Author: hitesh raigandhi (hiteshr )
  6. Environment:User Mode
  7. Revision History:
  8. --*/
  9. #include "stdafx.h"
  10. #include "utils.h"
  11. #include "dsace.h"
  12. #include "dsacls.h"
  13. /*******************************************************************
  14. NAME: GetAccountNameFromSid
  15. SYNOPSIS: Convert Sid to Account Name
  16. ENTRY: pszServerName: Server name at which to look for
  17. pSid : Pointer to Sid
  18. EXIT: ppszName : Gets pointer to Account Name
  19. RETURNS: ERROR_SUCCESS if Successful
  20. ERROR_NOT_ENOUGH_MEMORY
  21. NOTES: If LookupAccountName resolve the sid, it is
  22. converted in to string and returned
  23. HISTORY:
  24. hiteshr July-1999 Created
  25. ********************************************************************/
  26. DWORD GetAccountNameFromSid( LPWSTR pszServerName,
  27. PSID pSid,
  28. LPWSTR * ppszName )
  29. {
  30. LPWSTR pszAccountName = NULL;
  31. LPWSTR pszDomainName = NULL;
  32. DWORD cbAccountName = 0 ;
  33. DWORD cbDomainName = 0;
  34. SID_NAME_USE Use ;
  35. DWORD dwErr = ERROR_SUCCESS;
  36. *ppszName = NULL;
  37. if( LookupAccountSid( pszServerName, // name of local or remote computer
  38. pSid, // security identifier
  39. NULL, // account name buffer
  40. &cbAccountName,
  41. NULL ,
  42. &cbDomainName ,
  43. &Use ) == FALSE )
  44. {
  45. dwErr = GetLastError();
  46. if( dwErr != ERROR_INSUFFICIENT_BUFFER )
  47. {
  48. //Convert Sid to String
  49. if( !ConvertSidToStringSid( pSid, ppszName ) )
  50. dwErr = GetLastError();
  51. else
  52. dwErr = ERROR_SUCCESS;
  53. goto FAILURE_RETURN;
  54. }
  55. else
  56. dwErr = ERROR_SUCCESS;
  57. }
  58. pszAccountName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( cbAccountName +1 ) * sizeof( WCHAR ) );
  59. if( pszAccountName == NULL )
  60. {
  61. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  62. goto FAILURE_RETURN;
  63. }
  64. pszDomainName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( cbDomainName + 1 )* sizeof( WCHAR ) );
  65. if( pszDomainName == NULL )
  66. {
  67. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  68. goto FAILURE_RETURN;
  69. }
  70. if( LookupAccountSid( pszServerName, // name of local or remote computer
  71. pSid, // security identifier
  72. pszAccountName, // account name buffer
  73. &cbAccountName,
  74. pszDomainName ,
  75. &cbDomainName ,
  76. &Use ) == FALSE )
  77. {
  78. dwErr = GetLastError();
  79. goto FAILURE_RETURN;
  80. }
  81. *ppszName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( cbAccountName + cbDomainName + 2 ) * sizeof( WCHAR ) );
  82. if( *ppszName == NULL )
  83. {
  84. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  85. goto FAILURE_RETURN;
  86. }
  87. *ppszName[0] = NULL;
  88. if( cbDomainName )
  89. {
  90. wcscpy( *ppszName, pszDomainName );
  91. wcscat( *ppszName, L"\\" );
  92. }
  93. wcscat( *ppszName, pszAccountName );
  94. FAILURE_RETURN:
  95. if( pszDomainName )
  96. LocalFree( pszDomainName );
  97. if( pszAccountName )
  98. LocalFree( pszAccountName );
  99. return dwErr;
  100. }
  101. /*******************************************************************
  102. NAME: GetSidFromAccountName
  103. SYNOPSIS: Converts AccountName into SID
  104. ********************************************************************/
  105. DWORD GetSidFromAccountName( LPWSTR pszServerName,
  106. PSID *ppSid,
  107. LPWSTR pszName )
  108. {
  109. LPWSTR pszDomainName = NULL;
  110. DWORD cbSid = 0 ;
  111. DWORD cbDomainName = 0;
  112. SID_NAME_USE Use ;
  113. DWORD dwErr = ERROR_SUCCESS;
  114. if( LookupAccountName(pszServerName, // name of local or remote computer
  115. pszName, // security identifier
  116. NULL, // account name buffer
  117. &cbSid,
  118. NULL ,
  119. &cbDomainName ,
  120. &Use ) == FALSE )
  121. {
  122. dwErr = GetLastError();
  123. if( dwErr != ERROR_INSUFFICIENT_BUFFER )
  124. goto FAILURE_RETURN;
  125. else
  126. dwErr = ERROR_SUCCESS;
  127. }
  128. *ppSid = (PSID)LocalAlloc( LMEM_FIXED, cbSid );
  129. CHECK_NULL( *ppSid, FAILURE_RETURN );
  130. pszDomainName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( cbDomainName + 1 )* sizeof( WCHAR ) );
  131. CHECK_NULL( pszDomainName, FAILURE_RETURN );
  132. if( LookupAccountName( pszServerName, // name of local or remote computer
  133. pszName, // security identifier
  134. *ppSid, // account name buffer
  135. &cbSid,
  136. pszDomainName ,
  137. &cbDomainName ,
  138. &Use ) == FALSE )
  139. {
  140. dwErr = GetLastError();
  141. goto FAILURE_RETURN;
  142. }
  143. goto SUCCESS_RETURN;
  144. FAILURE_RETURN:
  145. if( pszDomainName )
  146. LocalFree( pszDomainName );
  147. if( *ppSid )
  148. LocalFree( *ppSid );
  149. SUCCESS_RETURN:
  150. return dwErr;
  151. }
  152. /*******************************************************************
  153. NAME: GetAceSid
  154. SYNOPSIS: Gets pointer to SID from an ACE
  155. ENTRY: pAce - pointer to ACE
  156. EXIT:
  157. RETURNS: Pointer to SID if successful, NULL otherwise
  158. NOTES:
  159. HISTORY:
  160. JeffreyS 08-Oct-1996 Created
  161. ********************************************************************/
  162. PSID
  163. GetAceSid(PACE_HEADER pAce)
  164. {
  165. switch (pAce->AceType)
  166. {
  167. case ACCESS_ALLOWED_ACE_TYPE:
  168. case ACCESS_DENIED_ACE_TYPE:
  169. case SYSTEM_AUDIT_ACE_TYPE:
  170. case SYSTEM_ALARM_ACE_TYPE:
  171. return (PSID)&((PKNOWN_ACE)pAce)->SidStart;
  172. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  173. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  174. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  175. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  176. return RtlObjectAceSid(pAce);
  177. }
  178. return NULL;
  179. }
  180. /*******************************************************************
  181. NAME: GetGlobalNamingContexts
  182. SYNOPSIS: Gets LDAP path for Schema and Extendend-Rights
  183. ENTRY: pszServerName, Server to bind to for query
  184. EXIT: pszSchemaNamingContext: Schema name in
  185. "LDAP:\\cn=schema,cn=..." format
  186. pszConfigurationNamingContext: Extendend rights path
  187. in "LDAP:\\CN=Extended-Rights,CN=Configuration..formats
  188. RETURNS: WIN32 Error Code
  189. ********************************************************************/
  190. DWORD GetGlobalNamingContexts( LPWSTR pszServerName,
  191. LPWSTR * pszSchemaNamingContext,
  192. LPWSTR * pszConfigurationNamingContext )
  193. {
  194. HRESULT hr = S_OK;
  195. DWORD dwErr = ERROR_SUCCESS;
  196. LPWSTR szSNC = NULL;
  197. ULONG uLen = 0;
  198. IADs *spRootDSE = NULL;
  199. LPWSTR pszRootDsePath = NULL;
  200. *pszSchemaNamingContext = NULL;
  201. *pszConfigurationNamingContext = NULL;
  202. if( pszServerName )
  203. uLen = wcslen(L"LDAP://") +
  204. wcslen( pszServerName ) +
  205. wcslen( L"/RootDSE") + 1;
  206. else
  207. uLen = wcslen(L"LDAP://RootDSE");
  208. pszRootDsePath = (LPWSTR)LocalAlloc( LMEM_FIXED, uLen * sizeof(WCHAR) );
  209. CHECK_NULL( pszRootDsePath,FAILURE_RETURN );
  210. wcscpy(pszRootDsePath, L"LDAP://");
  211. if( pszServerName )
  212. {
  213. wcscat( pszRootDsePath, pszServerName );
  214. wcscat( pszRootDsePath, L"/" );
  215. }
  216. wcscat( pszRootDsePath, L"RootDSE" );
  217. /*hr = ::ADsOpenObject( pszRootDsePath,
  218. NULL,
  219. NULL,
  220. ADS_SECURE_AUTHENTICATION,
  221. IID_IADs,
  222. (void**)&spRootDSE
  223. );
  224. */
  225. hr = ::ADsGetObject( pszRootDsePath,
  226. IID_IADs,
  227. (void**)&spRootDSE );
  228. CHECK_HR( hr, FAILURE_RETURN );
  229. VARIANT varSchemaNamingContext;
  230. hr = spRootDSE->Get(L"schemaNamingContext",
  231. &varSchemaNamingContext);
  232. CHECK_HR( hr, FAILURE_RETURN );
  233. szSNC = (LPWSTR)varSchemaNamingContext.bstrVal;
  234. uLen = wcslen( szSNC ) + 8 ; //For "LDAP:// + 1
  235. *pszSchemaNamingContext = (LPWSTR) LocalAlloc( LMEM_FIXED, uLen* sizeof(WCHAR) );
  236. CHECK_NULL( *pszSchemaNamingContext, FAILURE_RETURN );
  237. wcscpy( *pszSchemaNamingContext, L"LDAP://");
  238. wcscat( *pszSchemaNamingContext, szSNC );
  239. hr = spRootDSE->Get(L"configurationNamingContext",
  240. &varSchemaNamingContext);
  241. CHECK_HR( hr, FAILURE_RETURN );
  242. szSNC = (LPWSTR)varSchemaNamingContext.bstrVal;
  243. uLen = wcslen( szSNC ) + 27 + 1 ;
  244. *pszConfigurationNamingContext = (LPWSTR) LocalAlloc( LMEM_FIXED, uLen* sizeof(WCHAR) );
  245. CHECK_NULL( *pszConfigurationNamingContext,FAILURE_RETURN );
  246. wcscpy( *pszConfigurationNamingContext, L"LDAP://CN=Extended-Rights,");
  247. wcscat( *pszConfigurationNamingContext, szSNC );
  248. goto SUCCESS_RETURN;
  249. FAILURE_RETURN:
  250. if( *pszSchemaNamingContext )
  251. LocalFree( *pszSchemaNamingContext );
  252. if( *pszConfigurationNamingContext )
  253. LocalFree( *pszConfigurationNamingContext );
  254. SUCCESS_RETURN:
  255. if( spRootDSE )
  256. spRootDSE->Release();
  257. if( pszRootDsePath )
  258. LocalFree( pszRootDsePath );
  259. return dwErr;
  260. }
  261. /*******************************************************************
  262. NAME: FormatStringGUID
  263. SYNOPSIS: Given a GUID struct, it returns a GUID in string format,
  264. without {}
  265. //Function copied from marcoc code
  266. ********************************************************************/
  267. BOOL FormatStringGUID(LPWSTR lpszBuf, UINT nBufSize, const GUID* pGuid)
  268. {
  269. lpszBuf[0] = NULL;
  270. // if it is a NULL GUID*, just return an empty string
  271. if (pGuid == NULL)
  272. {
  273. return FALSE;
  274. }
  275. /*
  276. typedef struct _GUID {
  277. unsigned long Data1;
  278. unsigned short Data2;
  279. unsigned short Data3;
  280. unsigned char Data4[ 8 ];
  281. }
  282. int _snwprintf( wchar_t *buffer, size_t count, const wchar_t *format [, argume
  283. nt] ... );
  284. */
  285. return (_snwprintf(lpszBuf, nBufSize,
  286. L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  287. pGuid->Data1, pGuid->Data2, pGuid->Data3,
  288. pGuid->Data4[0], pGuid->Data4[1],
  289. pGuid->Data4[2], pGuid->Data4[3], pGuid->Data4[4], pGuid->Data4[5],
  290. pGuid->Data4[6], pGuid->Data4[7]) > 0);
  291. }
  292. /*
  293. Returns A string with n spaces
  294. */
  295. void StringWithNSpace( UINT n, LPWSTR szSpace )
  296. {
  297. for( UINT i = 0; i < n ; ++ i )
  298. szSpace[i] = L' ';
  299. szSpace[n] = 0;
  300. }
  301. /*
  302. Loads the string from Resource Table and
  303. Formats it
  304. */
  305. DWORD
  306. LoadMessage( IN DWORD MessageId, LPWSTR *ppszLoadString,...)
  307. {
  308. va_list ArgList;
  309. DWORD dwErr = ERROR_SUCCESS;
  310. va_start( ArgList, ppszLoadString );
  311. WCHAR szBuffer[1024];
  312. if( LoadString( g_hInstance,
  313. MessageId,
  314. szBuffer,
  315. 1023 ) == 0 )
  316. {
  317. dwErr = GetLastError();
  318. goto CLEAN_RETURN;
  319. }
  320. if( FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  321. szBuffer,
  322. MessageId,
  323. 0,
  324. ( PWSTR )ppszLoadString,
  325. 0,
  326. &ArgList ) == 0 )
  327. {
  328. dwErr = GetLastError();
  329. goto CLEAN_RETURN;
  330. }
  331. CLEAN_RETURN:
  332. va_end( ArgList );
  333. return dwErr;
  334. }
  335. /*******************************************************************
  336. NAME: DisplayString
  337. SYNOPSIS: Displays a string after inserting nIdent spaces
  338. ********************************************************************/
  339. VOID DisplayString( UINT nIdent, LPWSTR pszDisplay )
  340. {
  341. for ( UINT i = 0; i < nIdent; i++ )
  342. wprintf( L" " );
  343. wprintf(L"%s",pszDisplay);
  344. }
  345. VOID DisplayStringWithNewLine( UINT nIdent, LPWSTR pszDisplay )
  346. {
  347. DisplayString( nIdent, pszDisplay );
  348. wprintf(L"\n");
  349. }
  350. VOID DisplayNewLine()
  351. {
  352. wprintf(L"\n");
  353. }
  354. /*******************************************************************
  355. NAME: DisplayMessageEx
  356. SYNOPSIS: Loads Message from Resource and Formats its
  357. IN Indent - Number of tabs to indent
  358. MessageId - Id of the message to load
  359. ... - Optional list of parameters
  360. RETURNS: NONE
  361. ********************************************************************/
  362. DWORD
  363. DisplayMessageEx( DWORD nIndent, IN DWORD MessageId,...)
  364. {
  365. va_list ArgList;
  366. LPWSTR pszLoadString = NULL;
  367. va_start( ArgList, MessageId );
  368. WCHAR szBuffer[1024];
  369. if( LoadString( g_hInstance,
  370. MessageId,
  371. szBuffer,
  372. 1023 ) == 0 )
  373. {
  374. va_end( ArgList );
  375. return GetLastError();
  376. }
  377. if( FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  378. szBuffer,
  379. MessageId,
  380. 0,
  381. ( PWSTR )&pszLoadString,
  382. 0,
  383. &ArgList ) == 0 )
  384. {
  385. va_end( ArgList );
  386. return GetLastError();
  387. }
  388. DisplayStringWithNewLine( nIndent, pszLoadString );
  389. LocalFree( pszLoadString );
  390. return ERROR_SUCCESS;
  391. }
  392. BOOL GuidFromString(GUID* pGuid, LPCWSTR lpszGuidString)
  393. {
  394. ZeroMemory(pGuid, sizeof(GUID));
  395. if (lpszGuidString == NULL)
  396. {
  397. return FALSE;
  398. }
  399. int nLen = lstrlen(lpszGuidString);
  400. // the string length should be 36
  401. if (nLen != 36)
  402. return FALSE;
  403. // add the braces to call the Win32 API
  404. LPWSTR lpszWithBraces = (LPWSTR)LocalAlloc(LMEM_FIXED,((nLen+1+2)*sizeof(WCHAR)) ); // NULL plus {}
  405. if(!lpszWithBraces)
  406. return FALSE;
  407. wsprintf(lpszWithBraces, L"{%s}", lpszGuidString);
  408. return SUCCEEDED(::CLSIDFromString(lpszWithBraces, pGuid));
  409. }
  410. /*******************************************************************
  411. NAME: GetServerName
  412. SYNOPSIS: Get the name of the server. If Obeject Path is in form
  413. \\ADSERVER\CN=John..., then it gets the server name
  414. from Object Path and changes Object Path to CN=John...
  415. ********************************************************************/
  416. DWORD GetServerName( IN LPWSTR ObjectPath,
  417. OUT LPWSTR * ppszServerName )
  418. {
  419. DWORD Win32Err = ERROR_SUCCESS;
  420. PWSTR Separator = NULL;
  421. PDOMAIN_CONTROLLER_INFO DcInfo = NULL;
  422. PDOMAIN_CONTROLLER_INFO DcInfo1 = NULL;
  423. PWSTR Path = NULL;
  424. HANDLE DsHandle = NULL;
  425. PDS_NAME_RESULT NameRes = NULL;
  426. BOOLEAN NamedServer = FALSE;
  427. NTSTATUS Status;
  428. LPWSTR ServerName = NULL;
  429. //
  430. // Get a server name
  431. //
  432. if ( wcslen( ObjectPath ) > 2 && *ObjectPath == L'\\' && *( ObjectPath + 1 ) == L'\\' ) {
  433. Separator = wcschr( ObjectPath + 2, L'\\' );
  434. if ( Separator ) {
  435. *Separator = L'\0';
  436. Path = Separator + 1;
  437. }
  438. else
  439. return ERROR_INVALID_PARAMETER;
  440. ServerName = ObjectPath + 2;
  441. *ppszServerName = (LPWSTR)LocalAlloc(LMEM_FIXED,
  442. sizeof(WCHAR) * (wcslen(ServerName) + 1) );
  443. if( *ppszServerName == NULL )
  444. {
  445. if( Separator )
  446. *Separator = L'\\';
  447. return ERROR_NOT_ENOUGH_MEMORY;
  448. }
  449. wcscpy( *ppszServerName, ServerName );
  450. //Remove server name from object path
  451. memmove( ObjectPath, Path, ( wcslen(Path) + 1) * sizeof(WCHAR) );
  452. return ERROR_SUCCESS;
  453. } else {
  454. Path = ObjectPath;
  455. Win32Err = DsGetDcName( NULL,
  456. NULL,
  457. NULL,
  458. NULL,
  459. DS_DIRECTORY_SERVICE_REQUIRED,
  460. &DcInfo );
  461. if ( Win32Err == ERROR_SUCCESS ) {
  462. ServerName = DcInfo[ 0 ].DomainControllerName + 2;
  463. }
  464. }
  465. //
  466. // Do the bind and crack
  467. //
  468. if ( Win32Err == ERROR_SUCCESS ) {
  469. Win32Err = DsBind( ServerName,
  470. NULL,
  471. &DsHandle );
  472. if ( Win32Err == ERROR_SUCCESS ) {
  473. Win32Err = DsCrackNames( DsHandle,
  474. DS_NAME_NO_FLAGS,
  475. DS_FQDN_1779_NAME,
  476. DS_FQDN_1779_NAME,
  477. 1,
  478. &Path,
  479. &NameRes );
  480. if ( Win32Err == ERROR_SUCCESS ) {
  481. if ( NameRes->cItems != 0 &&
  482. NameRes->rItems[ 0 ].status == DS_NAME_ERROR_DOMAIN_ONLY ) {
  483. Win32Err = DsGetDcNameW( NULL,
  484. NameRes->rItems[ 0 ].pDomain,
  485. NULL,
  486. NULL,
  487. DS_DIRECTORY_SERVICE_REQUIRED,
  488. &DcInfo1 );
  489. if ( Win32Err == ERROR_SUCCESS ) {
  490. ServerName = DcInfo1->DomainControllerName + 2;
  491. }
  492. if( Win32Err == ERROR_INVALID_DOMAINNAME ||
  493. Win32Err == ERROR_NO_SUCH_DOMAIN )
  494. ServerName = NULL;
  495. }
  496. }
  497. }
  498. }
  499. if( ServerName )
  500. {
  501. *ppszServerName = (LPWSTR)LocalAlloc(LMEM_FIXED,
  502. sizeof(WCHAR) * (wcslen(ServerName) + 1) );
  503. if( *ppszServerName == NULL )
  504. return ERROR_NOT_ENOUGH_MEMORY;
  505. wcscpy( *ppszServerName, ServerName );
  506. Win32Err = ERROR_SUCCESS;
  507. }
  508. if( DcInfo )
  509. NetApiBufferFree( DcInfo );
  510. if( DcInfo1 )
  511. NetApiBufferFree( DcInfo1 );
  512. if( DsHandle )
  513. DsUnBindW( &DsHandle );
  514. if ( NameRes )
  515. DsFreeNameResult( NameRes );
  516. return Win32Err;
  517. }
  518. /*******************************************************************
  519. NAME: DisplayMessage
  520. SYNOPSIS: Loads Message from Message Table and Formats its
  521. IN Indent - Number of tabs to indent
  522. MessageId - Id of the message to load
  523. ... - Optional list of parameters
  524. RETURNS: NONE
  525. ********************************************************************/
  526. VOID
  527. DisplayMessage(
  528. IN DWORD Indent,
  529. IN DWORD MessageId,
  530. ...
  531. )
  532. /*++
  533. Routine Description:
  534. Loads the resource out of the executable and displays it.
  535. Arguments:
  536. Indent - Number of tabs to indent
  537. MessageId - Id of the message to load
  538. ... - Optional list of parameters
  539. Return Value:
  540. VOID
  541. --*/
  542. {
  543. PWSTR MessageDisplayString;
  544. va_list ArgList;
  545. ULONG Length, i;
  546. va_start( ArgList, MessageId );
  547. Length = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  548. NULL,
  549. MessageId,
  550. 0,
  551. ( PWSTR )&MessageDisplayString,
  552. 0,
  553. &ArgList );
  554. if ( Length != 0 ) {
  555. for ( i = 0; i < Indent; i++ ) {
  556. printf( "\t" );
  557. }
  558. printf( "%ws", MessageDisplayString );
  559. LocalFree( MessageDisplayString );
  560. }
  561. va_end( ArgList );
  562. }
  563. /*******************************************************************
  564. NAME: DisplayErrorMessage
  565. SYNOPSIS: Displays Error Message corresponding to Error
  566. RETURNS: NONE
  567. ********************************************************************/
  568. VOID
  569. DisplayErrorMessage(
  570. IN DWORD Error
  571. )
  572. {
  573. ULONG Size = 0;
  574. PWSTR DisplayString;
  575. ULONG Options = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM;
  576. Size = FormatMessage( Options,
  577. NULL,
  578. Error,
  579. MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
  580. ( LPTSTR )&DisplayString,
  581. 0,
  582. NULL );
  583. if ( Size != 0 ) {
  584. printf( "%ws\n", DisplayString );
  585. LocalFree( DisplayString );
  586. }
  587. }
  588. /*******************************************************************
  589. NAME: ConvertStringAToStringW
  590. SYNOPSIS: Converts MBYTE stirng to UNICODE
  591. RETURNS: ERROR_SUCCESS if success
  592. ERROR_NOT_ENOUGH_MEMORY
  593. ********************************************************************/
  594. DWORD
  595. ConvertStringAToStringW (
  596. IN PSTR AString,
  597. OUT PWSTR *WString
  598. )
  599. {
  600. DWORD Win32Err = ERROR_SUCCESS, Length;
  601. if ( AString == NULL ) {
  602. *WString = NULL;
  603. } else {
  604. Length = strlen( AString );
  605. *WString = ( PWSTR )LocalAlloc( LMEM_FIXED,
  606. ( mbstowcs( NULL, AString, Length + 1 ) + 1 ) *
  607. sizeof( WCHAR ) );
  608. if(*WString != NULL ) {
  609. mbstowcs( *WString, AString, Length + 1);
  610. } else {
  611. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  612. }
  613. }
  614. return( Win32Err );
  615. }
  616. /*******************************************************************
  617. NAME: CopyUnicodeString
  618. SYNOPSIS: Copy Unicode string from Source to Destination
  619. RETURNS: ERROR_SUCCESS if success
  620. ERROR_NOT_ENOUGH_MEMORY
  621. ********************************************************************/
  622. DWORD CopyUnicodeString( LPWSTR * strDst, LPWSTR strSrc )
  623. {
  624. *strDst = (LPWSTR)LocalAlloc( LMEM_FIXED , ( wcslen(strSrc) + 1 ) * sizeof(WCHAR ) );
  625. if ( !*strDst ) {
  626. return ERROR_NOT_ENOUGH_MEMORY;
  627. }
  628. wcscpy( *strDst, strSrc );
  629. return ERROR_SUCCESS;
  630. }
  631. /*******************************************************************
  632. NAME: GetProtection
  633. SYNOPSIS: Sets PROTECTED_DACL_SECURITY_INFORMATION in pSI,
  634. if SE_DACL_PROTECTED is set pSD
  635. RETURNS: ERROR_SUCCESS if success
  636. ********************************************************************/
  637. DWORD GetProtection( PSECURITY_DESCRIPTOR pSD, SECURITY_INFORMATION * pSI )
  638. {
  639. SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
  640. DWORD dwRevision;
  641. //
  642. ;
  643. if( !GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision) )
  644. {
  645. return GetLastError();
  646. }
  647. if ( wSDControl & SE_DACL_PROTECTED )
  648. *pSI |= PROTECTED_DACL_SECURITY_INFORMATION;
  649. return ERROR_SUCCESS;
  650. }
  651. /*******************************************************************
  652. NAME: BuildLdapPath
  653. SYNOPSIS: Builds a LDAP path using servername and path
  654. RETURNS: ERROR_SUCCESS if success
  655. ********************************************************************/
  656. DWORD BuildLdapPath( LPWSTR * ppszLdapPath,
  657. LPWSTR pszServerName,
  658. LPWSTR pszPath )
  659. {
  660. ULONG uLen = 0;
  661. if( pszServerName )
  662. uLen = wcslen( pszServerName ) + wcslen( pszPath );
  663. else
  664. uLen = wcslen( pszPath );
  665. uLen += 9; //LDAP://ServerName/path
  666. *ppszLdapPath = (LPWSTR)LocalAlloc( LMEM_FIXED, uLen * sizeof(WCHAR) );
  667. if( NULL == *ppszLdapPath )
  668. return ERROR_NOT_ENOUGH_MEMORY;
  669. wcscpy( * ppszLdapPath, L"LDAP://" );
  670. if( pszServerName )
  671. {
  672. wcscat( * ppszLdapPath, pszServerName );
  673. wcscat( * ppszLdapPath, L"/");
  674. }
  675. wcscat(* ppszLdapPath, pszPath );
  676. return ERROR_SUCCESS;
  677. }