195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */ 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 2004, Richard Levitte <richard@levitte.org> 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "directory.h" 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if defined(OPENSSL_WINDOWS) 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <windows.h> 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <tchar.h> 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <errno.h> 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#ifndef NAME_MAX 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define NAME_MAX 255 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystruct OPENSSL_dir_context_st { 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley WIN32_FIND_DATA ctx; 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley HANDLE handle; 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char entry_name[NAME_MAX + 1]; 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) { 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx == NULL || directory == NULL) { 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errno = EINVAL; 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errno = 0; 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*ctx == NULL) { 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ctx = malloc(sizeof(OPENSSL_DIR_CTX)); 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*ctx == NULL) { 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errno = ENOMEM; 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX)); 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sizeof(TCHAR) != sizeof(char)) { 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley TCHAR *wdir = NULL; 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* len_0 denotes string length *with* trailing 0 */ 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t index = 0, len_0 = strlen(directory) + 1; 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR)); 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (wdir == NULL) { 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley free(*ctx); 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ctx = NULL; 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errno = ENOMEM; 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len_0)) { 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (index = 0; index < len_0; index++) { 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley wdir[index] = (TCHAR)directory[index]; 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx); 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley free(wdir); 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx); 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((*ctx)->handle == INVALID_HANDLE_VALUE) { 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley free(*ctx); 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ctx = NULL; 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errno = EINVAL; 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) { 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sizeof(TCHAR) != sizeof(char)) { 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley TCHAR *wdir = (*ctx)->ctx.cFileName; 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t index, len_0 = 0; 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) { 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len_0++; 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len_0++; 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (*ctx)->entry_name, sizeof((*ctx)->entry_name), 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NULL, 0)) { 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (index = 0; index < len_0; index++) { 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (*ctx)->entry_name[index] = (char)wdir[index]; 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName, 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sizeof((*ctx)->entry_name) - 1); 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return (*ctx)->entry_name; 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) { 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx != NULL && *ctx != NULL) { 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley FindClose((*ctx)->handle); 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley free(*ctx); 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ctx = NULL; 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errno = EINVAL; 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif /* OPENSSL_WINDOWS */ 139