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.

932 lines
26 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 = ::ADsGetObject( pszRootDsePath,
  218. IID_IADs,
  219. (void**)&spRootDSE );
  220. CHECK_HR( hr, FAILURE_RETURN );
  221. //NTRAID#NTBUG9-537319-2002/03/20-hiteshr
  222. VARIANT varSchemaNamingContext;
  223. hr = spRootDSE->Get(AutoBstr(L"schemaNamingContext"),
  224. &varSchemaNamingContext);
  225. CHECK_HR( hr, FAILURE_RETURN );
  226. if(VT_BSTR != varSchemaNamingContext.vt)
  227. {
  228. hr = E_INVALIDARG;
  229. goto FAILURE_RETURN;
  230. }
  231. WCHAR szLdapPrefix[] = L"LDAP://";
  232. szSNC = (LPWSTR)varSchemaNamingContext.bstrVal;
  233. //For "LDAP:// + 1, ARRAYSIZE includes terminating null char
  234. uLen = wcslen( szSNC ) + ARRAYSIZE(szLdapPrefix); //For "LDAP:// + 1
  235. *pszSchemaNamingContext = (LPWSTR) LocalAlloc( LMEM_FIXED, uLen* sizeof(WCHAR) );
  236. CHECK_NULL( *pszSchemaNamingContext, FAILURE_RETURN );
  237. hr = StringCchCopy(*pszSchemaNamingContext, uLen, szLdapPrefix);
  238. CHECK_HR( hr, FAILURE_RETURN );
  239. hr = StringCchCat( *pszSchemaNamingContext, uLen, szSNC );
  240. CHECK_HR( hr, FAILURE_RETURN );
  241. //NTRAID#NTBUG9-537319-2002/03/20-hiteshr
  242. hr = spRootDSE->Get(AutoBstr(L"configurationNamingContext"),
  243. &varSchemaNamingContext);
  244. CHECK_HR( hr, FAILURE_RETURN );
  245. if(VT_BSTR != varSchemaNamingContext.vt)
  246. {
  247. hr = E_INVALIDARG;
  248. goto FAILURE_RETURN;
  249. }
  250. WCHAR szExtendedPrefix[] = L"LDAP://CN=Extended-Rights,";
  251. szSNC = (LPWSTR)varSchemaNamingContext.bstrVal;
  252. //For "LDAP://CN=Extended-Rights,". ARRAYSIZE include terminating NULL CHAR
  253. uLen = wcslen( szSNC ) + ARRAYSIZE(szExtendedPrefix);
  254. *pszConfigurationNamingContext = (LPWSTR) LocalAlloc( LMEM_FIXED, uLen* sizeof(WCHAR) );
  255. CHECK_NULL( *pszConfigurationNamingContext,FAILURE_RETURN );
  256. hr = StringCchCopy(*pszConfigurationNamingContext,uLen,szExtendedPrefix);
  257. CHECK_HR( hr, FAILURE_RETURN );
  258. hr = StringCchCat(*pszConfigurationNamingContext, uLen, szSNC);
  259. CHECK_HR( hr, FAILURE_RETURN );
  260. goto SUCCESS_RETURN;
  261. FAILURE_RETURN:
  262. if( *pszSchemaNamingContext )
  263. LocalFree( *pszSchemaNamingContext );
  264. if( *pszConfigurationNamingContext )
  265. LocalFree( *pszConfigurationNamingContext );
  266. SUCCESS_RETURN:
  267. if( spRootDSE )
  268. spRootDSE->Release();
  269. if( pszRootDsePath )
  270. LocalFree( pszRootDsePath );
  271. return dwErr;
  272. }
  273. /*******************************************************************
  274. NAME: FormatStringGUID
  275. SYNOPSIS: Given a GUID struct, it returns a GUID in string format,
  276. without {}
  277. //Function copied from marcoc code
  278. ********************************************************************/
  279. BOOL FormatStringGUID(LPWSTR lpszBuf, UINT nBufSize, const GUID* pGuid)
  280. {
  281. lpszBuf[0] = NULL;
  282. // if it is a NULL GUID*, just return an empty string
  283. if (pGuid == NULL)
  284. {
  285. return FALSE;
  286. }
  287. /*
  288. typedef struct _GUID {
  289. unsigned long Data1;
  290. unsigned short Data2;
  291. unsigned short Data3;
  292. unsigned char Data4[ 8 ];
  293. }
  294. int _snwprintf( wchar_t *buffer, size_t count, const wchar_t *format [, argume
  295. nt] ... );
  296. */
  297. return (_snwprintf(lpszBuf, nBufSize,
  298. L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  299. pGuid->Data1, pGuid->Data2, pGuid->Data3,
  300. pGuid->Data4[0], pGuid->Data4[1],
  301. pGuid->Data4[2], pGuid->Data4[3], pGuid->Data4[4], pGuid->Data4[5],
  302. pGuid->Data4[6], pGuid->Data4[7]) > 0);
  303. }
  304. /*
  305. Returns A string with n spaces
  306. */
  307. void StringWithNSpace( UINT n, LPWSTR szSpace )
  308. {
  309. for( UINT i = 0; i < n ; ++ i )
  310. szSpace[i] = L' ';
  311. szSpace[n] = 0;
  312. }
  313. /*
  314. Loads the string from Resource Table and
  315. Formats it
  316. */
  317. DWORD
  318. LoadMessage( IN DWORD MessageId, LPWSTR *ppszLoadString,...)
  319. {
  320. va_list ArgList;
  321. DWORD dwErr = ERROR_SUCCESS;
  322. va_start( ArgList, ppszLoadString );
  323. WCHAR szBuffer[1024];
  324. if( LoadString( g_hInstance,
  325. MessageId,
  326. szBuffer,
  327. 1023 ) == 0 )
  328. {
  329. dwErr = GetLastError();
  330. goto CLEAN_RETURN;
  331. }
  332. if( FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  333. szBuffer,
  334. MessageId,
  335. 0,
  336. ( PWSTR )ppszLoadString,
  337. 0,
  338. &ArgList ) == 0 )
  339. {
  340. dwErr = GetLastError();
  341. goto CLEAN_RETURN;
  342. }
  343. CLEAN_RETURN:
  344. va_end( ArgList );
  345. return dwErr;
  346. }
  347. /*******************************************************************
  348. NAME: DisplayString
  349. SYNOPSIS: Displays a string after inserting nIdent spaces
  350. ********************************************************************/
  351. VOID DisplayString( UINT nIdent, LPWSTR pszDisplay )
  352. {
  353. for ( UINT i = 0; i < nIdent; i++ )
  354. wprintf( L" " );
  355. wprintf(L"%s",pszDisplay);
  356. }
  357. VOID DisplayStringWithNewLine( UINT nIdent, LPWSTR pszDisplay )
  358. {
  359. DisplayString( nIdent, pszDisplay );
  360. wprintf(L"\n");
  361. }
  362. VOID DisplayNewLine()
  363. {
  364. wprintf(L"\n");
  365. }
  366. /*******************************************************************
  367. NAME: DisplayMessageEx
  368. SYNOPSIS: Loads Message from Resource and Formats its
  369. IN Indent - Number of tabs to indent
  370. MessageId - Id of the message to load
  371. ... - Optional list of parameters
  372. RETURNS: NONE
  373. ********************************************************************/
  374. DWORD
  375. DisplayMessageEx( DWORD nIndent, IN DWORD MessageId,...)
  376. {
  377. va_list ArgList;
  378. LPWSTR pszLoadString = NULL;
  379. va_start( ArgList, MessageId );
  380. WCHAR szBuffer[1024];
  381. if( LoadString( g_hInstance,
  382. MessageId,
  383. szBuffer,
  384. 1023 ) == 0 )
  385. {
  386. va_end( ArgList );
  387. return GetLastError();
  388. }
  389. if( FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  390. szBuffer,
  391. MessageId,
  392. 0,
  393. ( PWSTR )&pszLoadString,
  394. 0,
  395. &ArgList ) == 0 )
  396. {
  397. va_end( ArgList );
  398. return GetLastError();
  399. }
  400. DisplayStringWithNewLine( nIndent, pszLoadString );
  401. LocalFree( pszLoadString );
  402. return ERROR_SUCCESS;
  403. }
  404. BOOL GuidFromString(GUID* pGuid, LPCWSTR lpszGuidString)
  405. {
  406. ZeroMemory(pGuid, sizeof(GUID));
  407. if (lpszGuidString == NULL)
  408. {
  409. return FALSE;
  410. }
  411. int nLen = lstrlen(lpszGuidString);
  412. // the string length should be 36
  413. if (nLen != 36)
  414. return FALSE;
  415. // add the braces to call the Win32 API
  416. LPWSTR lpszWithBraces = (LPWSTR)LocalAlloc(LMEM_FIXED,((nLen+1+2)*sizeof(WCHAR)) ); // NULL plus {}
  417. if(!lpszWithBraces)
  418. return FALSE;
  419. wsprintf(lpszWithBraces, L"{%s}", lpszGuidString);
  420. return SUCCEEDED(::CLSIDFromString(lpszWithBraces, pGuid));
  421. }
  422. /*******************************************************************
  423. NAME: GetServerName
  424. SYNOPSIS: Get the name of the server. If Obeject Path is in form
  425. \\ADSERVER\CN=John..., then it gets the server name
  426. from Object Path and changes Object Path to CN=John...
  427. ********************************************************************/
  428. DWORD GetServerName( IN LPWSTR ObjectPath,
  429. OUT LPWSTR * ppszServerName )
  430. {
  431. DWORD Win32Err = ERROR_SUCCESS;
  432. PWSTR Separator = NULL;
  433. PDOMAIN_CONTROLLER_INFO DcInfo = NULL;
  434. PDOMAIN_CONTROLLER_INFO DcInfo1 = NULL;
  435. PWSTR Path = NULL;
  436. HANDLE DsHandle = NULL;
  437. PDS_NAME_RESULT NameRes = NULL;
  438. BOOLEAN NamedServer = FALSE;
  439. NTSTATUS Status;
  440. LPWSTR ServerName = NULL;
  441. //
  442. // Get a server name
  443. //
  444. if ( wcslen( ObjectPath ) > 2 && *ObjectPath == L'\\' && *( ObjectPath + 1 ) == L'\\' ) {
  445. Separator = wcschr( ObjectPath + 2, L'\\' );
  446. if ( Separator ) {
  447. *Separator = L'\0';
  448. Path = Separator + 1;
  449. }
  450. else
  451. return ERROR_INVALID_PARAMETER;
  452. ServerName = ObjectPath + 2;
  453. *ppszServerName = (LPWSTR)LocalAlloc(LMEM_FIXED,
  454. sizeof(WCHAR) * (wcslen(ServerName) + 1) );
  455. if( *ppszServerName == NULL )
  456. {
  457. if( Separator )
  458. *Separator = L'\\';
  459. return ERROR_NOT_ENOUGH_MEMORY;
  460. }
  461. wcscpy( *ppszServerName, ServerName );
  462. //Remove server name from object path
  463. memmove( ObjectPath, Path, ( wcslen(Path) + 1) * sizeof(WCHAR) );
  464. return ERROR_SUCCESS;
  465. } else {
  466. Path = ObjectPath;
  467. Win32Err = DsGetDcName( NULL,
  468. NULL,
  469. NULL,
  470. NULL,
  471. DS_DIRECTORY_SERVICE_REQUIRED,
  472. &DcInfo );
  473. if ( Win32Err == ERROR_SUCCESS ) {
  474. ServerName = DcInfo[ 0 ].DomainControllerName + 2;
  475. }
  476. }
  477. //
  478. // Do the bind and crack
  479. //
  480. if ( Win32Err == ERROR_SUCCESS ) {
  481. Win32Err = DsBind( ServerName,
  482. NULL,
  483. &DsHandle );
  484. if ( Win32Err == ERROR_SUCCESS ) {
  485. Win32Err = DsCrackNames( DsHandle,
  486. DS_NAME_NO_FLAGS,
  487. DS_FQDN_1779_NAME,
  488. DS_FQDN_1779_NAME,
  489. 1,
  490. &Path,
  491. &NameRes );
  492. if ( Win32Err == ERROR_SUCCESS ) {
  493. if ( NameRes->cItems != 0 &&
  494. NameRes->rItems[ 0 ].status == DS_NAME_ERROR_DOMAIN_ONLY ) {
  495. Win32Err = DsGetDcNameW( NULL,
  496. NameRes->rItems[ 0 ].pDomain,
  497. NULL,
  498. NULL,
  499. DS_DIRECTORY_SERVICE_REQUIRED,
  500. &DcInfo1 );
  501. if ( Win32Err == ERROR_SUCCESS ) {
  502. ServerName = DcInfo1->DomainControllerName + 2;
  503. }
  504. if( Win32Err == ERROR_INVALID_DOMAINNAME ||
  505. Win32Err == ERROR_NO_SUCH_DOMAIN )
  506. ServerName = NULL;
  507. }
  508. }
  509. }
  510. }
  511. if( ServerName )
  512. {
  513. *ppszServerName = (LPWSTR)LocalAlloc(LMEM_FIXED,
  514. sizeof(WCHAR) * (wcslen(ServerName) + 1) );
  515. if( *ppszServerName == NULL )
  516. return ERROR_NOT_ENOUGH_MEMORY;
  517. wcscpy( *ppszServerName, ServerName );
  518. Win32Err = ERROR_SUCCESS;
  519. }
  520. if( DcInfo )
  521. NetApiBufferFree( DcInfo );
  522. if( DcInfo1 )
  523. NetApiBufferFree( DcInfo1 );
  524. if( DsHandle )
  525. DsUnBindW( &DsHandle );
  526. if ( NameRes )
  527. DsFreeNameResult( NameRes );
  528. return Win32Err;
  529. }
  530. /*******************************************************************
  531. NAME: DisplayMessage
  532. SYNOPSIS: Loads Message from Message Table and Formats its
  533. IN Indent - Number of tabs to indent
  534. MessageId - Id of the message to load
  535. ... - Optional list of parameters
  536. RETURNS: NONE
  537. ********************************************************************/
  538. VOID
  539. DisplayMessage(
  540. IN DWORD Indent,
  541. IN DWORD MessageId,
  542. ...
  543. )
  544. /*++
  545. Routine Description:
  546. Loads the resource out of the executable and displays it.
  547. Arguments:
  548. Indent - Number of tabs to indent
  549. MessageId - Id of the message to load
  550. ... - Optional list of parameters
  551. Return Value:
  552. VOID
  553. --*/
  554. {
  555. PWSTR MessageDisplayString;
  556. va_list ArgList;
  557. ULONG Length, i;
  558. va_start( ArgList, MessageId );
  559. Length = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  560. NULL,
  561. MessageId,
  562. 0,
  563. ( PWSTR )&MessageDisplayString,
  564. 0,
  565. &ArgList );
  566. if ( Length != 0 ) {
  567. for ( i = 0; i < Indent; i++ ) {
  568. printf( "\t" );
  569. }
  570. printf( "%ws", MessageDisplayString );
  571. LocalFree( MessageDisplayString );
  572. }
  573. va_end( ArgList );
  574. }
  575. /*******************************************************************
  576. NAME: DisplayErrorMessage
  577. SYNOPSIS: Displays Error Message corresponding to Error
  578. RETURNS: NONE
  579. ********************************************************************/
  580. VOID
  581. DisplayErrorMessage(
  582. IN DWORD Error
  583. )
  584. {
  585. ULONG Size = 0;
  586. PWSTR DisplayString;
  587. ULONG Options = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM;
  588. Size = FormatMessage( Options,
  589. NULL,
  590. Error,
  591. MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
  592. ( LPTSTR )&DisplayString,
  593. 0,
  594. NULL );
  595. if ( Size != 0 ) {
  596. printf( "%ws\n", DisplayString );
  597. LocalFree( DisplayString );
  598. }
  599. }
  600. /*******************************************************************
  601. NAME: ConvertStringAToStringW
  602. SYNOPSIS: Converts MBYTE stirng to UNICODE
  603. RETURNS: ERROR_SUCCESS if success
  604. ERROR_NOT_ENOUGH_MEMORY
  605. ********************************************************************/
  606. DWORD
  607. ConvertStringAToStringW (
  608. IN PSTR AString,
  609. OUT PWSTR *WString
  610. )
  611. {
  612. DWORD Win32Err = ERROR_SUCCESS, Length;
  613. if ( AString == NULL ) {
  614. *WString = NULL;
  615. } else {
  616. Length = strlen( AString );
  617. *WString = ( PWSTR )LocalAlloc( LMEM_FIXED,
  618. ( mbstowcs( NULL, AString, Length + 1 ) + 1 ) *
  619. sizeof( WCHAR ) );
  620. if(*WString != NULL ) {
  621. mbstowcs( *WString, AString, Length + 1);
  622. } else {
  623. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  624. }
  625. }
  626. return( Win32Err );
  627. }
  628. /*******************************************************************
  629. NAME: CopyUnicodeString
  630. SYNOPSIS: Copy Unicode string from Source to Destination
  631. RETURNS: ERROR_SUCCESS if success
  632. ERROR_NOT_ENOUGH_MEMORY
  633. ********************************************************************/
  634. DWORD CopyUnicodeString( LPWSTR * strDst, LPWSTR strSrc )
  635. {
  636. *strDst = (LPWSTR)LocalAlloc( LMEM_FIXED , ( wcslen(strSrc) + 1 ) * sizeof(WCHAR ) );
  637. if ( !*strDst ) {
  638. return ERROR_NOT_ENOUGH_MEMORY;
  639. }
  640. wcscpy( *strDst, strSrc );
  641. return ERROR_SUCCESS;
  642. }
  643. /*******************************************************************
  644. NAME: GetProtection
  645. SYNOPSIS: Sets PROTECTED_DACL_SECURITY_INFORMATION in pSI,
  646. if SE_DACL_PROTECTED is set pSD
  647. RETURNS: ERROR_SUCCESS if success
  648. ********************************************************************/
  649. DWORD GetProtection( PSECURITY_DESCRIPTOR pSD, SECURITY_INFORMATION * pSI )
  650. {
  651. SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
  652. DWORD dwRevision;
  653. //
  654. ;
  655. if( !GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision) )
  656. {
  657. return GetLastError();
  658. }
  659. if ( wSDControl & SE_DACL_PROTECTED )
  660. *pSI |= PROTECTED_DACL_SECURITY_INFORMATION;
  661. return ERROR_SUCCESS;
  662. }
  663. /*******************************************************************
  664. NAME: BuildLdapPath
  665. SYNOPSIS: Builds a LDAP path using servername and path
  666. RETURNS: ERROR_SUCCESS if success
  667. ********************************************************************/
  668. DWORD BuildLdapPath( LPWSTR * ppszLdapPath,
  669. LPWSTR pszServerName,
  670. LPWSTR pszPath )
  671. {
  672. ULONG uLen = 0;
  673. if( pszServerName )
  674. uLen = wcslen( pszServerName ) + wcslen( pszPath );
  675. else
  676. uLen = wcslen( pszPath );
  677. WCHAR szLDAPPrefix[] = L"LDAP://";
  678. //+1 for '/' after server name.ArraySize includes null char
  679. uLen += ARRAYSIZE(szLDAPPrefix) + 1; //LDAP://ServerName/path
  680. *ppszLdapPath = (LPWSTR)LocalAlloc( LMEM_FIXED, uLen * sizeof(WCHAR) );
  681. if( NULL == *ppszLdapPath )
  682. return ERROR_NOT_ENOUGH_MEMORY;
  683. HRESULT hr = StringCchCopy( * ppszLdapPath, uLen, L"LDAP://" );
  684. if(FAILED(hr))
  685. {
  686. LocalFree(*ppszLdapPath);
  687. return HRESULT_CODE(hr);
  688. }
  689. if( pszServerName )
  690. {
  691. hr = StringCchCat( * ppszLdapPath, uLen, pszServerName );
  692. if(FAILED(hr))
  693. {
  694. LocalFree(*ppszLdapPath);
  695. return HRESULT_CODE(hr);
  696. }
  697. hr = StringCchCat(* ppszLdapPath, uLen, L"/");
  698. if(FAILED(hr))
  699. {
  700. LocalFree(*ppszLdapPath);
  701. return HRESULT_CODE(hr);
  702. }
  703. }
  704. hr = StringCchCat(* ppszLdapPath, uLen, pszPath );
  705. if(FAILED(hr))
  706. {
  707. LocalFree(*ppszLdapPath);
  708. return HRESULT_CODE(hr);
  709. }
  710. return ERROR_SUCCESS;
  711. }