/* * Copyright Likewise Software 2004-2009 * All rights reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the license, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. You should have received a copy * of the GNU Lesser General Public License along with this program. If * not, see . * * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU * LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT * license@likewisesoftware.com */ /* * Copyright (C) Likewise Software. All rights reserved. * * Module Name: * * test_ptlwregd.c * * Abstract: * * Registry * * Multi-threaded lwregd test client * * Authors: Adam Bernstein (abernstein@likewise.com) */ #define TEST_ADD 0 #define TEST_DELETE 1 #define TEST_GET_KEY 2 #define TEST_GET_VALUE 3 #define LWREGD_MAX_THEADS 2 #define LWREGD_MAX_ITERATIONS 10 #include "includes.h" #include "rsutils.h" typedef struct _PTLWREGD_CONTEXT { HANDLE hReg; pthread_t thread; PSTR pszKeyPath; PSTR pszKeyNamePrefix; DWORD dwRange; DWORD dwIterations; DWORD dwOperation; } PTLWREGD_CONTEXT, *PPTLWREGD_CONTEXT; DWORD ThreadTestAddKey( HANDLE hReg, PSTR pszKeyPath, PSTR pszKeyNamePrefix, DWORD dwRange, DWORD dwIterations) { DWORD dwError = 0; DWORD dwCount = 0; DWORD dwKeyNum = 0; PSTR pszKeyName = NULL; PSTR pszSubKeyPath = NULL; for (dwCount=0; dwCount>ThreadTestAddKey: %d %s\\%s\n", dwCount, pszKeyPath, pszKeyName); dwError = RegCStringAllocatePrintf( &pszSubKeyPath, "%s\\%s", pszKeyPath, pszKeyName); BAIL_ON_REG_ERROR(dwError); dwError = RegShellUtilAddKey(hReg, NULL, pszSubKeyPath, pszKeyName, FALSE); BAIL_ON_REG_ERROR(dwError); printf(" >>ThreadTestAddKey: %d %s\\%s\n", dwCount, pszSubKeyPath, pszKeyName); } } cleanup: LWREG_SAFE_FREE_STRING(pszKeyName); LWREG_SAFE_FREE_STRING(pszSubKeyPath); return dwError; error: if (dwError) { RegPrintError("ThreadTestAddKey", dwError); } goto cleanup; } DWORD ThreadTestGetKeys( HANDLE hReg, PSTR pszKeyPath, PSTR pszKeyNamePrefix, DWORD dwRange, DWORD dwIterations) { DWORD dwError = 0; DWORD dwCount = 0; DWORD dwKeyNum = 0; PSTR pszKeyName = NULL; LW_WCHAR **ppSubKeys = NULL; DWORD dwRetSubKeyCount = 0; int i = 0; for (dwCount=0; dwCount>ThreadTestGetKeys: %d %s\\%s has %d subkeys\n", dwCount, pszKeyPath, pszKeyName, dwRetSubKeyCount); } } cleanup: for (i = 0; i < dwRetSubKeyCount; i++) { LWREG_SAFE_FREE_MEMORY(ppSubKeys[i]); } LWREG_SAFE_FREE_MEMORY(ppSubKeys); LWREG_SAFE_FREE_STRING(pszKeyName); return dwError; error: if (dwError) { RegPrintError("ThreadTestGetKeys", dwError); } goto cleanup; } DWORD ThreadTestGetValues( HANDLE hReg, PSTR pszKeyPath, PSTR pszKeyNamePrefix, DWORD dwRange, DWORD dwIterations) { DWORD dwError = 0; DWORD dwCount = 0; DWORD dwKeyNum = 0; PSTR pszKeyName = NULL; PREGSHELL_UTIL_VALUE valueArray = NULL; DWORD dwValueArrayLen = 0; int i = 0; for (dwCount=0; dwCount>ThreadTestGetValues: %d %s\\%s has %d value\n", dwCount, pszKeyPath, pszKeyName, dwValueArrayLen); } } cleanup: for (i=0; i>ThreadTestDeleteKey: %d %s\\%s\n", dwCount, pszSubKeyPath, pszKeyName); dwError = RegShellUtilDeleteKey(hReg, NULL, pszKeyPath, pszKeyName); BAIL_ON_REG_ERROR(dwError); printf(" >>ThreadTestDeleteKey: %d %s\\%s\n", dwCount, pszKeyPath, pszKeyName); } } cleanup: LWREG_SAFE_FREE_STRING(pszKeyName); LWREG_SAFE_FREE_STRING(pszSubKeyPath); return dwError; error: if (dwError == LWREG_ERROR_FAILED_DELETE_HAS_SUBKEY || dwError == LWREG_ERROR_KEY_IS_ACTIVE || dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE) { dwError = 0; } if (dwError) { RegPrintError("ThreadTestDeleteKey", dwError); } goto cleanup; } void * ThreadTestPtKey( void *pctx) { DWORD dwError = 0; PPTLWREGD_CONTEXT context = (PPTLWREGD_CONTEXT) pctx; PSTR pszOperation = NULL; switch (context->dwOperation) { case TEST_ADD: pszOperation = "AddKey"; break; case TEST_DELETE: pszOperation = "DeleteKey"; break; case TEST_GET_KEY: pszOperation = "GetKeys"; break; case TEST_GET_VALUE: pszOperation = "GetValues"; break; default: pszOperation = "Undefined"; } printf("ThreadTestPt%sKey: starting %s\\%s\n", pszOperation, context->pszKeyPath, context->pszKeyNamePrefix); switch (context->dwOperation) { case TEST_ADD: dwError = ThreadTestAddKey( context->hReg, context->pszKeyPath, context->pszKeyNamePrefix, context->dwRange, context->dwIterations); break; case TEST_DELETE: dwError = ThreadTestDeleteKey( context->hReg, context->pszKeyPath, context->pszKeyNamePrefix, context->dwRange, context->dwIterations); break; case TEST_GET_KEY: dwError = ThreadTestGetKeys( context->hReg, context->pszKeyPath, context->pszKeyNamePrefix, context->dwRange, context->dwIterations); break; case TEST_GET_VALUE: dwError = ThreadTestGetValues( context->hReg, context->pszKeyPath, context->pszKeyNamePrefix, context->dwRange, context->dwIterations); pszOperation = "GetValues"; break; default: pszOperation = "Undefined"; } BAIL_ON_REG_ERROR(dwError); printf("ThreadTestPt%sKey: %s\\%s done.\n", pszOperation, context->pszKeyPath, context->pszKeyNamePrefix); cleanup: return NULL; error: goto cleanup; } DWORD ThreadTestPtFree( PPTLWREGD_CONTEXT pCtx) { DWORD dwError = 0; BAIL_ON_INVALID_HANDLE(pCtx); RegCloseServer(pCtx->hReg); RegMemoryFree(pCtx->pszKeyNamePrefix); RegMemoryFree(pCtx->pszKeyPath); RegMemoryFree(pCtx); cleanup: return dwError; error: goto cleanup; } DWORD ThreadTestPtInit( PSTR pszKeyPath, PSTR pszKeyNamePrefix, DWORD dwKeyNameSuffix, DWORD dwIterations, DWORD dwOperation, PPTLWREGD_CONTEXT *ppRetCtx) { PPTLWREGD_CONTEXT pCtx = NULL; DWORD dwError = 0; HANDLE hReg = NULL; dwError = RegAllocateMemory(sizeof(*pCtx), (PVOID*)&pCtx); BAIL_ON_REG_ERROR(dwError); dwError = RegOpenServer(&hReg); BAIL_ON_REG_ERROR(dwError); dwError = RegCStringDuplicate(&pCtx->pszKeyPath, pszKeyPath); BAIL_ON_REG_ERROR(dwError); dwError = RegAllocateMemory(strlen(pszKeyNamePrefix) + 11, (PVOID*)&pCtx->pszKeyNamePrefix); BAIL_ON_REG_ERROR(dwError); sprintf(pCtx->pszKeyNamePrefix, "%s%d", pszKeyNamePrefix, dwKeyNameSuffix); pCtx->hReg = hReg; pCtx->dwRange = 1000; pCtx->dwIterations = dwIterations; pCtx->dwOperation = dwOperation; *ppRetCtx = pCtx; cleanup: return dwError; error: goto cleanup; } int main(int argc, char *argv[]) { PPTLWREGD_CONTEXT ctxAdd[LWREGD_MAX_THEADS] = {0}; PPTLWREGD_CONTEXT ctxDel[LWREGD_MAX_THEADS] = {0}; PPTLWREGD_CONTEXT ctxGetKeys[LWREGD_MAX_THEADS] = {0}; PPTLWREGD_CONTEXT ctxGetValues[LWREGD_MAX_THEADS] = {0}; DWORD dwError = 0; int sts = 0; DWORD i = 0; for (i=0; ithread, NULL, ThreadTestPtKey, ctxAdd[i]); if (sts == -1) { printf("pthread_create: Error ThreadTestPtAddkey(ctxAdd[%d])\n", i); return 1; } } for (i=0; ithread, NULL, ThreadTestPtKey, ctxDel[i]); if (sts == -1) { printf("pthread_create: Error ThreadTestPtDeletekey(ctxDel[%d])\n", i); return 1; } } for (i=0; ithread, NULL, ThreadTestPtKey, ctxGetKeys[i]); if (sts == -1) { printf("pthread_create: Error ThreadTestPtGetKeys(ctxGetKeys[%d])\n", i); return 1; } } for (i=0; ithread, NULL, ThreadTestPtKey, ctxGetValues[i]); if (sts == -1) { printf("pthread_create: Error ThreadTestPtGetValues(ctxGetValues[%d])\n", i); return 1; } } for (i=0; ithread, NULL); pthread_join(ctxDel[i]->thread, NULL); pthread_join(ctxGetKeys[i]->thread, NULL); pthread_join(ctxGetValues[i]->thread, NULL); } for (i=0; i