From e5215158d27fe9527d089a6ea493b09fe37c51d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 25 Sep 2011 16:30:20 -0400 Subject: [PATCH] wfreerdp: start Win32 GDI implementation, fix certstore --- client/Windows/CMakeLists.txt | 4 + client/Windows/wf_event.c | 204 ++++++++++++++++++++++++++++++++++++++++++ client/Windows/wf_event.h | 36 ++++++++ client/Windows/wf_gdi.c | 103 +++++++++++++++++++++ client/Windows/wf_gdi.h | 31 +++++++ client/Windows/wfreerdp.c | 103 +++++++++++++++++++-- client/Windows/wfreerdp.h | 10 ++- libfreerdp-core/tls.c | 8 +- libfreerdp-utils/certstore.c | 4 +- libfreerdp-utils/registry.c | 2 +- 10 files changed, 489 insertions(+), 16 deletions(-) create mode 100644 client/Windows/wf_event.c create mode 100644 client/Windows/wf_event.h create mode 100644 client/Windows/wf_gdi.c create mode 100644 client/Windows/wf_gdi.h diff --git a/client/Windows/CMakeLists.txt b/client/Windows/CMakeLists.txt index 04af456..1ac4998 100644 --- a/client/Windows/CMakeLists.txt +++ b/client/Windows/CMakeLists.txt @@ -18,6 +18,10 @@ # limitations under the License. add_executable(wfreerdp WIN32 + wf_gdi.c + wf_gdi.h + wf_event.c + wf_event.h wfreerdp.c wfreerdp.h) diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c new file mode 100644 index 0000000..c6ac3fe --- /dev/null +++ b/client/Windows/wf_event.c @@ -0,0 +1,204 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Event Handling + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "wfreerdp.h" + +#include "wf_event.h" + +static HWND g_focus_hWnd; +extern HCURSOR g_default_cursor; + +#define X_POS(lParam) (lParam & 0xffff) +#define Y_POS(lParam) ((lParam >> 16) & 0xffff) + +LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) +{ + DWORD flags; + wfInfo* wfi; + uint8 scanCode; + rdpInput* input; + uint16 kbdFlags; + PKBDLLHOOKSTRUCT p; + + DEBUG_KBD("Low-level keyboard hook, hWnd %X nCode %X wParam %X\n", g_focus_hWnd, nCode, wParam); + + if (g_focus_hWnd && (nCode == HC_ACTION)) + { + switch (wParam) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA); + p = (PKBDLLHOOKSTRUCT) lParam; + scanCode = (uint8) p->scanCode; + input = wfi->instance->input; + flags = p->flags; + kbdFlags = 0; + + DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X\n", + (wParam == WM_KEYDOWN), scanCode, flags, p->vkCode); + + if (wfi->fs_toggle && + ((p->vkCode == VK_RETURN) || (p->vkCode == VK_CANCEL)) && + (GetAsyncKeyState(VK_CONTROL) & 0x8000) && + (GetAsyncKeyState(VK_MENU) & 0x8000)) /* could also use flags & LLKHF_ALTDOWN */ + { + if (wParam == WM_KEYDOWN) + //wf_toggle_fullscreen(wfi); + return 1; + } + + if (scanCode == 0x45) /* NumLock-ish */ + { + if (flags & LLKHF_EXTENDED) + { + /* Windows sends NumLock as extended - rdp doesn't */ + DEBUG_KBD("hack: NumLock (x45) should not be extended\n"); + flags &= ~LLKHF_EXTENDED; + } + else + { + /* Windows sends Pause as if it was a RDP NumLock (handled above). + * It must however be sent as a one-shot Ctrl+NumLock */ + if (wParam == WM_KEYDOWN) + { + DEBUG_KBD("Pause, sent as Ctrl+NumLock\n"); + input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x1D); /* Ctrl down */ + input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x45); /* NumLock down */ + input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x1D); /* Ctrl up */ + input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x45); /* NumLock up */ + } + else + { + DEBUG_KBD("Pause up\n"); + } + + return 1; + } + } + + if ((scanCode == 0x36) && (flags & LLKHF_EXTENDED)) + { + DEBUG_KBD("hack: right shift (x36) should not be extended\n"); + flags &= ~LLKHF_EXTENDED; + } + + kbdFlags |= (flags & LLKHF_UP) ? KBD_FLAGS_RELEASE : KBD_FLAGS_DOWN; + kbdFlags |= (flags & LLKHF_EXTENDED) ? KBD_FLAGS_EXTENDED : 0; + input->KeyboardEvent(input, kbdFlags, scanCode); + + if (p->vkCode == VK_CAPITAL) + DEBUG_KBD("caps lock is processed on client side too to toggle caps lock indicator\n"); + else + return 1; + + break; + } + } + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + LONG ptr; + wfInfo* wfi; + PAINTSTRUCT ps; + rdpInput* input; + + ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA); + wfi = (wfInfo*) ptr; + input = wfi->instance->input; + + switch (Msg) + { + case WM_DESTROY: + PostQuitMessage(WM_QUIT); + break; + + case WM_PAINT: + if (wfi != NULL) + { + hdc = BeginPaint(hWnd, &ps); + BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top, + wfi->primary->hdc, ps.rcPaint.left, ps.rcPaint.top, + SRCCOPY); + EndPaint(hWnd, &ps); + } + break; + + case WM_LBUTTONDOWN: + if (wfi != NULL) + input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_LBUTTONUP: + if (wfi != NULL) + input->MouseEvent(input, PTR_FLAGS_BUTTON1, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_RBUTTONDOWN: + if (wfi != NULL) + input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_RBUTTONUP: + if (wfi != NULL) + input->MouseEvent(input, PTR_FLAGS_BUTTON2, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_MOUSEMOVE: + if (wfi != NULL) + input->MouseEvent(input, PTR_FLAGS_MOVE, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_SETCURSOR: + if (wfi != NULL) + SetCursor(wfi->cursor); + else + SetCursor(g_default_cursor); + break; + + case WM_SETFOCUS: + DEBUG_KBD("getting focus %X\n", hWnd); + g_focus_hWnd = hWnd; + break; + + case WM_KILLFOCUS: + DEBUG_KBD("loosing focus %X\n", hWnd); + if (g_focus_hWnd == hWnd) + g_focus_hWnd = NULL; + break; + + default: + return DefWindowProc(hWnd, Msg, wParam, lParam); + break; + } + + return 0; +} diff --git a/client/Windows/wf_event.h b/client/Windows/wf_event.h new file mode 100644 index 0000000..7924e4e --- /dev/null +++ b/client/Windows/wf_event.h @@ -0,0 +1,36 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Event Handling + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WF_EVENT_H +#define __WF_EVENT_H + +#include "wfreerdp.h" + +LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + +#ifdef WITH_DEBUG_KBD +#define DEBUG_KBD(fmt, ...) DEBUG_CLASS(KBD, fmt, ## __VA_ARGS__) +#else +#define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c new file mode 100644 index 0000000..f4877ec --- /dev/null +++ b/client/Windows/wf_gdi.c @@ -0,0 +1,103 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows GDI + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include + +#include "wfreerdp.h" + +HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data) +{ + HDC hdc; + int negHeight; + HBITMAP bitmap; + BITMAPINFO bmi; + uint8* cdata = NULL; + + /** + * See: http://msdn.microsoft.com/en-us/library/dd183376 + * if biHeight is positive, the bitmap is bottom-up + * if biHeight is negative, the bitmap is top-down + * Since we get top-down bitmaps, let's keep it that way + */ + + negHeight = (height < 0) ? height : height * (-1); + + hdc = GetDC(NULL); + bmi.bmiHeader.biSize = sizeof(BITMAPINFO); + bmi.bmiHeader.biWidth = width; + bmi.bmiHeader.biHeight = negHeight; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 24; + bmi.bmiHeader.biCompression = BI_RGB; + bitmap = CreateDIBSection (hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); + + if (data != NULL) + freerdp_image_convert(data, cdata, width, height, bpp, 24, wfi->clrconv); + + ReleaseDC(NULL, hdc); + GdiFlush(); + + return bitmap; +} + +WF_IMAGE* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) +{ + HDC hdc; + WF_IMAGE* image; + + hdc = GetDC(NULL); + image = (WF_IMAGE*) malloc(sizeof(WF_IMAGE)); + image->hdc = CreateCompatibleDC(hdc); + + if (data == NULL) + image->bitmap = CreateCompatibleBitmap(hdc, width, height); + else + image->bitmap = wf_create_dib(wfi, width, height, bpp, data); + + image->org_bitmap = (HBITMAP) SelectObject(image->hdc, image->bitmap); + ReleaseDC(NULL, hdc); + + return image; +} + +void wf_image_free(WF_IMAGE* image) +{ + if (image != 0) + { + SelectObject(image->hdc, image->org_bitmap); + DeleteObject(image->bitmap); + DeleteDC(image->hdc); + free(image); + } +} + +void wf_toggle_fullscreen(wfInfo* wfi) +{ + ShowWindow(wfi->hwnd, SW_HIDE); + wfi->fullscreen = !wfi->fullscreen; + SetForegroundWindow(wfi->hwnd); +} diff --git a/client/Windows/wf_gdi.h b/client/Windows/wf_gdi.h new file mode 100644 index 0000000..61ce614 --- /dev/null +++ b/client/Windows/wf_gdi.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows GDI + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WF_GDI_H +#define __WF_GDI_H + +#include "wfreerdp.h" + +WF_IMAGE* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); +void wf_image_free(WF_IMAGE* image); +void wf_toggle_fullscreen(wfInfo* wfi); + +#endif /* __WF_GDI_H */ diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 04b019f..1ad1ef2 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -30,6 +30,8 @@ #include #include +#include "wf_gdi.h" + #include "wfreerdp.h" struct _thread_data @@ -57,6 +59,7 @@ int wf_create_console(void) boolean wf_pre_connect(freerdp* instance) { + int i1; wfInfo* wfi; rdpSettings* settings; @@ -88,6 +91,37 @@ boolean wf_pre_connect(freerdp* instance) settings->order_support[NEG_ELLIPSE_SC_INDEX] = False; settings->order_support[NEG_ELLIPSE_CB_INDEX] = False; + wfi->cursor = g_default_cursor; + + wfi->fullscreen = settings->fullscreen; + wfi->fs_toggle = wfi->fullscreen; + + if (wfi->percentscreen > 0) + { + i1 = (GetSystemMetrics(SM_CXSCREEN) * wfi->percentscreen) / 100; + settings->width = i1; + + i1 = (GetSystemMetrics(SM_CYSCREEN) * wfi->percentscreen) / 100; + settings->height = i1; + } + + if (wfi->fs_toggle) + { + settings->width = GetSystemMetrics(SM_CXSCREEN); + settings->height = GetSystemMetrics(SM_CYSCREEN); + } + + i1 = settings->width; + i1 = (i1 + 3) & (~3); + settings->width = i1; + + if ((settings->width < 64) || (settings->height < 64) || + (settings->width > 4096) || (settings->height > 4096)) + { + printf("wf_pre_connect: invalid dimensions %d %d\n", settings->width, settings->height); + return 1; + } + settings->kbd_layout = (int) GetKeyboardLayout(0) & 0x0000FFFF; freerdp_chanman_pre_connect(GET_CHANMAN(instance), instance); @@ -98,13 +132,65 @@ boolean wf_post_connect(freerdp* instance) { GDI* gdi; wfInfo* wfi; + int width, height; + wchar_t win_title[64]; + rdpSettings* settings; wfi = GET_WFI(instance); SET_WFI(instance->update, wfi); + settings = instance->settings; gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP); gdi = GET_GDI(instance->update); + width = settings->width; + height = settings->height; + + if (strlen(wfi->window_title) > 0) + _snwprintf(win_title, sizeof(win_title), L"%S", wfi->window_title); + else if (settings->port == 3389) + _snwprintf(win_title, sizeof(win_title) / sizeof(win_title[0]), L"%S - FreeRDP", settings->hostname); + else + _snwprintf(win_title, sizeof(win_title) / sizeof(win_title[0]), L"%S:%d - FreeRDP", settings->hostname, settings->port); + + if (wfi->hwnd == 0) + { + wfi->hwnd = CreateWindowEx((DWORD) NULL, g_wnd_class_name, win_title, + 0, 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL); + + SetWindowLongPtr(wfi->hwnd, GWLP_USERDATA, (LONG_PTR) wfi); + } + + if (wfi->fullscreen) + { + SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP); + SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED); + } + else + { + POINT diff; + RECT rc_client, rc_wnd; + + SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX); + /* Now resize to get full canvas size and room for caption and borders */ + SetWindowPos(wfi->hwnd, HWND_TOP, 10, 10, width, height, SWP_FRAMECHANGED); + GetClientRect(wfi->hwnd, &rc_client); + GetWindowRect(wfi->hwnd, &rc_wnd); + diff.x = (rc_wnd.right - rc_wnd.left) - rc_client.right; + diff.y = (rc_wnd.bottom - rc_wnd.top) - rc_client.bottom; + SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, width + diff.x, height + diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); + } + + if (wfi->primary == NULL) + { + wfi->primary = wf_image_new(wfi, width, height, 0, NULL); + BitBlt(wfi->primary->hdc, 0, 0, width, height, NULL, 0, 0, BLACKNESS); + } + wfi->drawing = wfi->primary; + + ShowWindow(wfi->hwnd, SW_SHOWNORMAL); + UpdateWindow(wfi->hwnd); + freerdp_chanman_post_connect(GET_CHANMAN(instance), instance); return True; @@ -279,6 +365,7 @@ static DWORD WINAPI thread_func(LPVOID lpParam) wfi->clrconv->alpha = 1; wfi->clrconv->palette = NULL; SET_WFI(instance, wfi); + wfi->instance = instance; wfreerdp_run(instance); @@ -292,18 +379,17 @@ static DWORD WINAPI thread_func(LPVOID lpParam) static DWORD WINAPI kbd_thread_func(LPVOID lpParam) { -#if 0 MSG msg; - BOOL bRet; + BOOL status; HHOOK hook_handle; hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, g_hInstance, 0); if (hook_handle) { - while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) + while( (status = GetMessage( &msg, NULL, 0, 0 )) != 0) { - if (bRet == -1) + if (status == -1) { printf("keyboard thread error getting message\n"); break; @@ -318,7 +404,6 @@ static DWORD WINAPI kbd_thread_func(LPVOID lpParam) } else printf("failed to install keyboard hook\n"); -#endif return (DWORD) NULL; } @@ -344,7 +429,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine wnd_cls.cbSize = sizeof(WNDCLASSEX); wnd_cls.style = CS_HREDRAW | CS_VREDRAW; - //wnd_cls.lpfnWndProc = wf_event_proc; + wnd_cls.lpfnWndProc = wf_event_proc; wnd_cls.cbClsExtra = 0; wnd_cls.cbWndExtra = 0; wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION); @@ -370,7 +455,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (!CreateThread(NULL, 0, kbd_thread_func, NULL, 0, NULL)) printf("error creating keyboard handler thread"); - while (1) + //while (1) { data = (thread_data*) xzalloc(sizeof(thread_data)); data->instance = instance; @@ -391,5 +476,9 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine WSACleanup(); +#ifdef _DEBUG + system("pause"); +#endif + return 0; } diff --git a/client/Windows/wfreerdp.h b/client/Windows/wfreerdp.h index 1baec46..358bac3 100644 --- a/client/Windows/wfreerdp.h +++ b/client/Windows/wfreerdp.h @@ -35,18 +35,21 @@ #include #include +#include "wf_event.h" + #define SET_WFI(_instance, _wfi) (_instance)->param1 = _wfi #define GET_WFI(_instance) ((wfInfo*) ((_instance)->param1)) #define SET_CHANMAN(_instance, _chanman) (_instance)->param2 = _chanman #define GET_CHANMAN(_instance) ((rdpChanMan*) ((_instance)->param2)) -struct wf_bitmap +struct _WF_IMAGE { HDC hdc; HBITMAP bitmap; HBITMAP org_bitmap; }; +typedef struct _WF_IMAGE WF_IMAGE; struct wf_info { @@ -56,8 +59,9 @@ struct wf_info char window_title[64]; HWND hwnd; - struct wf_bitmap* primary; - struct wf_bitmap* drawing; + freerdp* instance; + WF_IMAGE* primary; + WF_IMAGE* drawing; HCLRCONV clrconv; HCURSOR cursor; HBRUSH brush; diff --git a/libfreerdp-core/tls.c b/libfreerdp-core/tls.c index 271fab8..55af6f1 100644 --- a/libfreerdp-core/tls.c +++ b/libfreerdp-core/tls.c @@ -244,11 +244,11 @@ rdpTls* tls_new() int tls_verify_certificate(CryptoCert cert, char* hostname) { - boolean ret; + boolean status; rdpCertstore* certstore; - ret = x509_verify_cert(cert); + status = x509_verify_cert(cert); - if (!ret) + if (status != True) { rdpCertdata* certdata; certdata = crypto_get_certdata(cert->px509, hostname); @@ -262,6 +262,7 @@ int tls_verify_certificate(CryptoCert cert, char* hostname) char answer; crypto_cert_printinfo(cert->px509); +#ifndef _WIN32 while (1) { printf("Do you trust the above certificate? (Y/N) "); @@ -278,6 +279,7 @@ int tls_verify_certificate(CryptoCert cert, char* hostname) return 1; } } +#endif } else if (certstore->match == -1) { diff --git a/libfreerdp-utils/certstore.c b/libfreerdp-utils/certstore.c index e0e93af..e6c1d3e 100644 --- a/libfreerdp-utils/certstore.c +++ b/libfreerdp-utils/certstore.c @@ -76,7 +76,7 @@ char* get_local_certloc() #ifndef _WIN32 mkdir(certloc, S_IRUSR | S_IWUSR | S_IXUSR); #else - CreateDirectory(certloc, 0); + CreateDirectoryA(certloc, 0); #endif } @@ -108,7 +108,7 @@ void certstore_init(rdpCertstore* certstore) #ifndef _WIN32 mkdir(certstore->path, S_IRUSR | S_IWUSR | S_IXUSR); #else - CreateDirectory(certstore->path, 0); + CreateDirectoryA(certstore->path, 0); #endif printf("creating directory %s\n", certstore->path); } diff --git a/libfreerdp-utils/registry.c b/libfreerdp-utils/registry.c index ab426cb..f50053e 100644 --- a/libfreerdp-utils/registry.c +++ b/libfreerdp-utils/registry.c @@ -149,7 +149,7 @@ void registry_init(rdpRegistry* registry) #ifndef _WIN32 mkdir(registry->path, S_IRUSR | S_IWUSR | S_IXUSR); #else - CreateDirectory(registry->path, 0); + CreateDirectoryA(registry->path, 0); #endif printf("creating directory %s\n", registry->path); } -- 2.7.4