示例#1
0
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);
    }
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
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;
}