static NTSTATUS DfsConfigRootAddReferrals( HANDLE hRegistryServer, HKEY hParentKey, PDFS_ROOT_CONTROL_BLOCK pRootCB ) { NTSTATUS ntStatus = STATUS_SUCCESS; HKEY hDfsRootKey = (HKEY)NULL; PDFS_REFERRAL_CONTROL_BLOCK pReferralCB = NULL; PWSTR *ppwszTargets = NULL; DWORD i = 0; DWORD dwIndex = 0; BOOLEAN bFinished = FALSE; DWORD dwValueNameLength = MAX_VALUE_LENGTH; WCHAR pwszValueName[MAX_VALUE_LENGTH] = { 0 }; DWORD dwType = REG_NONE; DWORD dwReserved = 0; BYTE pBuffer[4096] = { 0 }; DWORD dwBufferSize = 0; ntStatus = NtRegOpenKeyExW( hRegistryServer, hParentKey, pRootCB->pwszRootName, 0, KEY_READ, &hDfsRootKey); BAIL_ON_NT_STATUS(ntStatus); for (dwIndex=0; !bFinished; dwIndex++) { dwBufferSize = sizeof(pBuffer); LwRtlZeroMemory(pBuffer, dwBufferSize); ntStatus = NtRegEnumValueW( hRegistryServer, hDfsRootKey, dwIndex, pwszValueName, &dwValueNameLength, &dwReserved, &dwType, pBuffer, &dwBufferSize); if (ntStatus == STATUS_NO_MORE_ENTRIES) { ntStatus = STATUS_SUCCESS; bFinished = TRUE; continue; } BAIL_ON_NT_STATUS(ntStatus); if (dwType != REG_MULTI_SZ) { continue; } ntStatus = NtRegByteArrayToMultiStrsW( pBuffer, dwBufferSize, &ppwszTargets); BAIL_ON_NT_STATUS(ntStatus); ntStatus = DfsAllocateReferralCB(&pReferralCB, pwszValueName); BAIL_ON_NT_STATUS(ntStatus); for (i=0; ppwszTargets[i] != NULL; i++) { ntStatus = DfsReferralParseTarget(pReferralCB, ppwszTargets[i]); BAIL_ON_NT_STATUS(ntStatus); } RegFreeMultiStrsW(ppwszTargets); ppwszTargets = NULL; } cleanup: if (hDfsRootKey) { NtRegCloseKey(hRegistryServer, hDfsRootKey); } return ntStatus; error: goto cleanup; }
NTSTATUS SrvShareRegEnum( HANDLE hRepository, HANDLE hResume, PSRV_SHARE_INFO** pppShareInfoList, PULONG pulNumSharesFound ) { NTSTATUS ntStatus = 0; ULONG ulIndex = 0; ULONG ulBatchIndex = 0; HKEY hRootKey = NULL; HKEY hKey = NULL; HKEY hSecKey = NULL; PWSTR pwszValueName = NULL; PBYTE pData = NULL; REG_DATA_TYPE dataType = REG_UNKNOWN; wchar16_t wszHKTM[] = HKEY_THIS_MACHINE_W; wchar16_t wszSharesKey[] = REG_KEY_PATH_SRV_SHARES_W; wchar16_t wszShareSecKey[] = REG_KEY_PATH_SRV_SHARES_SECURITY_W; PSRV_SHARE_INFO* ppShareInfoList = NULL; REG_DATA_TYPE dataSecType = REG_UNKNOWN; ULONG ulNumSharesFound = 0; BYTE pSecData[MAX_VALUE_LENGTH] = {0}; PSRV_SHARE_REG_ENUM_CONTEXT pResume = (PSRV_SHARE_REG_ENUM_CONTEXT)hResume; if (!pResume) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NtRegOpenKeyExW( hRepository, NULL, &wszHKTM[0], 0, KEY_READ, &hRootKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegOpenKeyExW( hRepository, hRootKey, &wszSharesKey[0], 0, KEY_READ, &hKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegOpenKeyExW( hRepository, hRootKey, &wszShareSecKey[0], 0, KEY_READ, &hSecKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvAllocateMemory( pResume->ulBatchLimit * sizeof(*ppShareInfoList), (PVOID) &ppShareInfoList); BAIL_ON_NT_STATUS(ntStatus); ulBatchIndex = pResume->ulBatchIndex; for (ulIndex = 0; ulIndex < pResume->ulBatchLimit; ulIndex++) { ULONG ulMaxValueNameLen = 0; ULONG ulMaxValueLen = 0; ULONG ulMaxSecValueLen = 0; ulMaxValueNameLen = (pResume->ulMaxValueNameLen + 1) * sizeof(*pwszValueName); ulMaxValueLen = pResume->ulMaxValueLen; ulMaxSecValueLen = MAX_VALUE_LENGTH; if (ulMaxValueNameLen) { SRV_SAFE_FREE_MEMORY_AND_RESET(pwszValueName); ntStatus = SrvAllocateMemory( ulMaxValueNameLen, (PVOID*) &pwszValueName); BAIL_ON_NT_STATUS(ntStatus); } if (ulMaxValueLen) { SRV_SAFE_FREE_MEMORY_AND_RESET(pData); ntStatus = SrvAllocateMemory(ulMaxValueLen, (PVOID*) &pData); BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NtRegEnumValueW( hRepository, hKey, ulBatchIndex++, pwszValueName, &ulMaxValueNameLen, NULL, &dataType, pData, &ulMaxValueLen); if (ntStatus == STATUS_NO_MORE_MATCHES || ntStatus == STATUS_NO_MORE_ENTRIES) { ntStatus = STATUS_SUCCESS; break; } BAIL_ON_NT_STATUS(ntStatus); if (REG_MULTI_SZ != dataType) { continue; } ntStatus = NtRegGetValueW( hRepository, hSecKey, NULL, pwszValueName, RRF_RT_REG_BINARY, &dataSecType, pSecData, &ulMaxSecValueLen); if (STATUS_OBJECT_NAME_NOT_FOUND == ntStatus) { ntStatus = 0; ulMaxSecValueLen = 0; } BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvShareRegWriteToShareInfo( dataType, pwszValueName, pData, ulMaxValueLen, dataSecType, pSecData, ulMaxSecValueLen, &ppShareInfoList[ulNumSharesFound++]); BAIL_ON_NT_STATUS(ntStatus); } pResume->ulBatchIndex = ulBatchIndex; *pppShareInfoList = ppShareInfoList; *pulNumSharesFound = ulNumSharesFound; cleanup: if (hRootKey) { NtRegCloseKey(hRepository, hRootKey); } if (hKey) { NtRegCloseKey(hRepository, hKey); } if (hSecKey) { NtRegCloseKey(hRepository, hSecKey); } SRV_SAFE_FREE_MEMORY(pwszValueName); SRV_SAFE_FREE_MEMORY(pData); return ntStatus; error: *pppShareInfoList = NULL; *pulNumSharesFound = 0; if (ppShareInfoList) { SrvShareFreeInfoList(ppShareInfoList, ulNumSharesFound); } goto cleanup; }