VOID NtRegCloseConfig( PLWREG_CONFIG_REG pReg ) { if (pReg) { LwRtlCStringFree(&pReg->pszConfigKey); LwRtlCStringFree(&pReg->pszPolicyKey); if (pReg->hConnection) { if ( pReg->hKey ) { NtRegCloseKey(pReg->hConnection, pReg->hKey); pReg->hKey = NULL; } NtRegCloseServer(pReg->hConnection); pReg->hConnection = NULL; } RTL_FREE(&pReg); } }
NTSTATUS SrvShareRegDelete( IN HANDLE hRepository, IN PWSTR pwszShareName ) { NTSTATUS ntStatus = 0; HKEY hRootKey = NULL; 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; ntStatus = NtRegOpenKeyExW( hRepository, NULL, &wszHKTM[0], 0, KEY_ALL_ACCESS, &hRootKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegDeleteKeyValueW( hRepository, hRootKey, &wszSharesKey[0], pwszShareName); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegDeleteKeyValueW( hRepository, hRootKey, &wszShareSecKey[0], pwszShareName); if (STATUS_OBJECT_NAME_NOT_FOUND == ntStatus) { ntStatus = STATUS_SUCCESS; } BAIL_ON_NT_STATUS(ntStatus); cleanup: if (hRootKey) { NtRegCloseKey(hRepository, hRootKey); } return ntStatus; error: goto cleanup; }
NTSTATUS DfsConfigReadStandaloneRoots( VOID ) { NTSTATUS ntStatus = STATUS_SUCCESS; HANDLE hRegConnection = (HANDLE)NULL; HKEY hStandaloneKey = (HKEY)NULL; PWSTR pwszStandaloneRootKeyPath = NULL; DWORD dwIndex = 0; DWORD dwReserved = 0; DWORD dwDfsRootNameSize = MAX_KEY_LENGTH; WCHAR pwszDfsRootName[MAX_KEY_LENGTH] = {0}; BOOLEAN bFinished = FALSE; ntStatus = LwRtlWC16StringAllocateFromCString( &pwszStandaloneRootKeyPath, DFS_CONF_ROOT_STANDALONE); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegOpenServer(&hRegConnection); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegOpenKeyExW( hRegConnection, NULL, pwszStandaloneRootKeyPath, 0, KEY_READ, &hStandaloneKey); BAIL_ON_NT_STATUS(ntStatus); for (dwIndex = 0; !bFinished; dwIndex++) { ntStatus = NtRegEnumKeyExW( hRegConnection, hStandaloneKey, dwIndex, pwszDfsRootName, &dwDfsRootNameSize, &dwReserved, NULL, NULL, NULL); if (ntStatus == STATUS_NO_MORE_ENTRIES) { ntStatus = STATUS_SUCCESS; bFinished = TRUE; continue; } BAIL_ON_NT_STATUS(ntStatus); ntStatus = DfsConfigInitializeRoot( hRegConnection, hStandaloneKey, pwszDfsRootName); BAIL_ON_NT_STATUS(ntStatus); } cleanup: if (pwszStandaloneRootKeyPath) { LwRtlWC16StringFree(&pwszStandaloneRootKeyPath); } if (hStandaloneKey) { NtRegCloseKey(hRegConnection, hStandaloneKey); } if (hRegConnection) { NtRegCloseServer(hRegConnection); } return ntStatus; error: goto cleanup; }
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 SrvShareRegFindByName( HANDLE hRepository, PWSTR pwszShareName, PSRV_SHARE_INFO* ppShareInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; HKEY hRootKey = NULL; HKEY hKey = NULL; HKEY hSecKey = NULL; REG_DATA_TYPE dataType = REG_UNKNOWN; ULONG ulValueLen = MAX_VALUE_LENGTH; REG_DATA_TYPE dataSecType = REG_UNKNOWN; ULONG ulSecValueLen = MAX_VALUE_LENGTH; PSRV_SHARE_INFO pShareInfo = NULL; BYTE pData[MAX_VALUE_LENGTH] = {0}; BYTE pSecData[MAX_VALUE_LENGTH] = {0}; 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; 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 = NtRegGetValueW( hRepository, hKey, NULL, pwszShareName, RRF_RT_REG_MULTI_SZ, &dataType, pData, &ulValueLen); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegGetValueW( hRepository, hSecKey, NULL, pwszShareName, RRF_RT_REG_BINARY, &dataSecType, pSecData, &ulSecValueLen); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvShareRegWriteToShareInfo( dataType, pwszShareName, pData, ulValueLen, dataSecType, pSecData, ulSecValueLen, &pShareInfo); BAIL_ON_NT_STATUS(ntStatus); *ppShareInfo = pShareInfo; cleanup: if (hRootKey) { NtRegCloseKey(hRepository, hRootKey); } if (hKey) { NtRegCloseKey(hRepository, hKey); } if (hSecKey) { NtRegCloseKey(hRepository, hSecKey); } return ntStatus; error: if (pShareInfo) { SrvShareReleaseInfo(pShareInfo); } goto cleanup; }
NTSTATUS SrvShareRegGetCount( IN HANDLE hRepository, IN OUT PULONG pulNumShares ) { NTSTATUS ntStatus = 0; ULONG ulNumShares = 0; HKEY hRootKey = NULL; HKEY hKey = NULL; wchar16_t wszHKTM[] = HKEY_THIS_MACHINE_W; wchar16_t wszSharesKey[] = REG_KEY_PATH_SRV_SHARES_W; 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 = NtRegQueryInfoKeyW( hRepository, hKey, NULL, NULL, NULL, NULL, NULL, NULL, &ulNumShares, NULL, NULL, NULL, NULL); BAIL_ON_NT_STATUS(ntStatus); *pulNumShares = ulNumShares; cleanup: if (hRootKey) { NtRegCloseKey(hRepository, hRootKey); } if (hKey) { NtRegCloseKey(hRepository, hKey); } return ntStatus; error: *pulNumShares = 0; 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; }
NTSTATUS SrvShareRegBeginEnum( HANDLE hRepository, ULONG ulBatchLimit, PHANDLE phResume ) { NTSTATUS ntStatus = 0; HKEY hRootKey = NULL; HKEY hKey = NULL; wchar16_t wszHKTM[] = HKEY_THIS_MACHINE_W; wchar16_t wszSharesKey[] = REG_KEY_PATH_SRV_SHARES_W; PSRV_SHARE_REG_ENUM_CONTEXT pEnumContext = NULL; if (!ulBatchLimit || (ulBatchLimit == UINT32_MAX)) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = SrvAllocateMemory( sizeof(SRV_SHARE_REG_ENUM_CONTEXT), (PVOID*)&pEnumContext); 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 = NtRegQueryInfoKeyW( hRepository, hKey, NULL, NULL, NULL, NULL, NULL, NULL, &pEnumContext->ulValuesAvailable, &pEnumContext->ulMaxValueNameLen, &pEnumContext->ulMaxValueLen, NULL, NULL); BAIL_ON_NT_STATUS(ntStatus); pEnumContext->ulBatchLimit = ulBatchLimit; *phResume = (HANDLE)pEnumContext; cleanup: if (hRootKey) { NtRegCloseKey(hRepository, hRootKey); } if (hKey) { NtRegCloseKey(hRepository, hKey); } return ntStatus; error: *phResume = NULL; SRV_SAFE_FREE_MEMORY(pEnumContext); goto cleanup; }
NTSTATUS SrvShareRegAdd( IN HANDLE hRepository, IN PWSTR pwszShareName, IN PWSTR pwszPath, IN PWSTR pwszComment, IN PBYTE pSecDesc, IN ULONG ulSecDescLen, IN PWSTR pwszService, IN ULONG ulFlags ) { NTSTATUS ntStatus = 0; HKEY hRootKey = NULL; HKEY hKey = NULL; HKEY hSecKey = NULL; PWSTR* ppwszValues = NULL; PBYTE pOutData = NULL; SSIZE_T cOutDataLen = 0; PWSTR pwszFlags = NULL; ULONG ulCount = 0; 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; wchar16_t wszPathPrefix[] = REG_KEY_PATH_PREFIX_W; wchar16_t wszFlagsPrefix[] = REG_KEY_FLAGS_PREFIX_W; ULONG ulPathPrefixLen = (sizeof(wszPathPrefix)/sizeof(wchar16_t)) - 1; ULONG ulFlagsPrefixLen = (sizeof(wszFlagsPrefix)/sizeof(wchar16_t)) - 1; if (IsNullOrEmptyString(pwszShareName)) { ntStatus = STATUS_INVALID_PARAMETER_2; BAIL_ON_NT_STATUS(ntStatus); } if (IsNullOrEmptyString(pwszPath)) { ntStatus = STATUS_INVALID_PARAMETER_3; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NtRegOpenKeyExW( hRepository, NULL, &wszHKTM[0], 0, KEY_ALL_ACCESS, &hRootKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegOpenKeyExW( hRepository, hRootKey, &wszSharesKey[0], 0, KEY_ALL_ACCESS, &hKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvAllocateMemory(sizeof(PWSTR) * 5, (PVOID*)&ppwszValues); BAIL_ON_NT_STATUS(ntStatus); // Path ntStatus = SrvAllocateMemory( sizeof(wszPathPrefix) + wc16slen(pwszPath) * sizeof(wchar16_t), (PVOID*)&ppwszValues[ulCount]); BAIL_ON_NT_STATUS(ntStatus); memcpy( (PBYTE)&ppwszValues[ulCount][0], (PBYTE)&wszPathPrefix[0], sizeof(wszPathPrefix) - sizeof(wchar16_t)); memcpy( (PBYTE)&ppwszValues[ulCount][ulPathPrefixLen], (PBYTE)pwszPath, wc16slen(pwszPath) * sizeof(wchar16_t)); if (!IsNullOrEmptyString(pwszComment)) { wchar16_t wszCommentPrefix[] = REG_KEY_COMMENT_PREFIX_W; ULONG ulCommentPrefixLen = (sizeof(wszCommentPrefix)/sizeof(wchar16_t)) - 1; ntStatus = SrvAllocateMemory( sizeof(wszCommentPrefix) + wc16slen(pwszComment) * sizeof(wchar16_t), (PVOID*)&ppwszValues[++ulCount]); BAIL_ON_NT_STATUS(ntStatus); memcpy( (PBYTE)&ppwszValues[ulCount][0], (PBYTE)&wszCommentPrefix[0], sizeof(wszCommentPrefix) - sizeof(wchar16_t)); memcpy( (PBYTE)&ppwszValues[ulCount][ulCommentPrefixLen], (PBYTE)pwszComment, wc16slen(pwszComment) * sizeof(wchar16_t)); } if (!IsNullOrEmptyString(pwszService)) { wchar16_t wszServicePrefix[] = REG_KEY_SERVICE_PREFIX_W; ULONG ulServicePrefixLen = (sizeof(wszServicePrefix)/sizeof(wchar16_t)) - 1; ntStatus = SrvAllocateMemory( sizeof(wszServicePrefix) + wc16slen(pwszService) * sizeof(wchar16_t), (PVOID*)&ppwszValues[++ulCount]); BAIL_ON_NT_STATUS(ntStatus); memcpy( (PBYTE)&ppwszValues[ulCount][0], (PBYTE)&wszServicePrefix[0], sizeof(wszServicePrefix) - sizeof(wchar16_t)); memcpy( (PBYTE)&ppwszValues[ulCount][ulServicePrefixLen], (PBYTE)pwszService, wc16slen(pwszService) * sizeof(wchar16_t)); } // Flags ntStatus = LwRtlWC16StringAllocatePrintfW(&pwszFlags, L"0x%08x", ulFlags); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvAllocateMemory( sizeof(wszFlagsPrefix) + wc16slen(pwszFlags) * sizeof(wchar16_t), OUT_PPVOID(&ppwszValues[++ulCount])); BAIL_ON_NT_STATUS(ntStatus); memcpy((PBYTE)&ppwszValues[ulCount][0], (PBYTE)&wszFlagsPrefix[0], sizeof(wszFlagsPrefix) - sizeof(wchar16_t)); memcpy((PBYTE)&ppwszValues[ulCount][ulFlagsPrefixLen], (PBYTE)pwszFlags, wc16slen(pwszFlags) * sizeof(wchar16_t)); ntStatus = NtRegMultiStrsToByteArrayW(ppwszValues, &pOutData, &cOutDataLen); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegSetValueExW( hRepository, hKey, pwszShareName, 0, REG_MULTI_SZ, pOutData, cOutDataLen); BAIL_ON_NT_STATUS(ntStatus); if ((pSecDesc && !ulSecDescLen) || (!pSecDesc && ulSecDescLen)) { ntStatus = STATUS_INVALID_PARAMETER_5; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NtRegOpenKeyExW( hRepository, hRootKey, &wszShareSecKey[0], 0, KEY_ALL_ACCESS, &hSecKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegSetValueExW( hRepository, hSecKey, pwszShareName, 0, REG_BINARY, pSecDesc, ulSecDescLen); BAIL_ON_NT_STATUS(ntStatus); cleanup: if (hRootKey) { NtRegCloseKey(hRepository, hRootKey); } if (hKey) { NtRegCloseKey(hRepository, hKey); } if (hSecKey) { NtRegCloseKey(hRepository, hSecKey); } if (ppwszValues) { SrvShareFreeStringArray(ppwszValues, 4); } if (pOutData) { RegFreeMemory(pOutData); } RTL_FREE(&pwszFlags); return ntStatus; error: goto cleanup; }