FreeRDP
Loading...
Searching...
No Matches
device.c
1
20#include <winpr/config.h>
21
22#include <winpr/io.h>
23
24#ifndef _WIN32
25
26#include "io.h"
27
28#include <stdio.h>
29#include <fcntl.h>
30#include <stdlib.h>
31#include <errno.h>
32
33#ifdef WINPR_HAVE_UNISTD_H
34#include <unistd.h>
35#endif
36
37#include <sys/types.h>
38#include <sys/stat.h>
39
40#include <winpr/crt.h>
41#include <winpr/path.h>
42#include <winpr/file.h>
43
63#define DEVICE_FILE_PREFIX_PATH "\\Device\\"
64
65static char* GetDeviceFileNameWithoutPrefixA(LPCSTR lpName)
66{
67 char* lpFileName = NULL;
68
69 if (!lpName)
70 return NULL;
71
72 if (strncmp(lpName, DEVICE_FILE_PREFIX_PATH, sizeof(DEVICE_FILE_PREFIX_PATH) - 1) != 0)
73 return NULL;
74
75 lpFileName =
76 _strdup(&lpName[strnlen(DEVICE_FILE_PREFIX_PATH, sizeof(DEVICE_FILE_PREFIX_PATH))]);
77 return lpFileName;
78}
79
80static char* GetDeviceFileUnixDomainSocketBaseFilePathA(void)
81{
82 char* lpTempPath = NULL;
83 char* lpPipePath = NULL;
84 lpTempPath = GetKnownPath(KNOWN_PATH_TEMP);
85
86 if (!lpTempPath)
87 return NULL;
88
89 lpPipePath = GetCombinedPath(lpTempPath, ".device");
90 free(lpTempPath);
91 return lpPipePath;
92}
93
94static char* GetDeviceFileUnixDomainSocketFilePathA(LPCSTR lpName)
95{
96 char* lpPipePath = NULL;
97 char* lpFileName = NULL;
98 char* lpFilePath = NULL;
99 lpPipePath = GetDeviceFileUnixDomainSocketBaseFilePathA();
100
101 if (!lpPipePath)
102 return NULL;
103
104 lpFileName = GetDeviceFileNameWithoutPrefixA(lpName);
105
106 if (!lpFileName)
107 {
108 free(lpPipePath);
109 return NULL;
110 }
111
112 lpFilePath = GetCombinedPath(lpPipePath, lpFileName);
113 free(lpPipePath);
114 free(lpFileName);
115 return lpFilePath;
116}
117
123NTSTATUS _IoCreateDeviceEx(WINPR_ATTR_UNUSED PDRIVER_OBJECT_EX DriverObject,
124 WINPR_ATTR_UNUSED ULONG DeviceExtensionSize, PUNICODE_STRING DeviceName,
125 WINPR_ATTR_UNUSED DEVICE_TYPE DeviceType,
126 WINPR_ATTR_UNUSED ULONG DeviceCharacteristics,
127 WINPR_ATTR_UNUSED BOOLEAN Exclusive, PDEVICE_OBJECT_EX* DeviceObject)
128{
129 int status = 0;
130 char* DeviceBasePath = NULL;
131 DEVICE_OBJECT_EX* pDeviceObjectEx = NULL;
132 DeviceBasePath = GetDeviceFileUnixDomainSocketBaseFilePathA();
133
134 if (!DeviceBasePath)
135 return STATUS_NO_MEMORY;
136
137 if (!winpr_PathFileExists(DeviceBasePath))
138 {
139 if (mkdir(DeviceBasePath, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
140 {
141 free(DeviceBasePath);
142 return STATUS_ACCESS_DENIED;
143 }
144 }
145
146 free(DeviceBasePath);
147 pDeviceObjectEx = (DEVICE_OBJECT_EX*)calloc(1, sizeof(DEVICE_OBJECT_EX));
148
149 if (!pDeviceObjectEx)
150 return STATUS_NO_MEMORY;
151
152 pDeviceObjectEx->DeviceName =
153 ConvertWCharNToUtf8Alloc(DeviceName->Buffer, DeviceName->Length / sizeof(WCHAR), NULL);
154 if (!pDeviceObjectEx->DeviceName)
155 {
156 free(pDeviceObjectEx);
157 return STATUS_NO_MEMORY;
158 }
159
160 pDeviceObjectEx->DeviceFileName =
161 GetDeviceFileUnixDomainSocketFilePathA(pDeviceObjectEx->DeviceName);
162
163 if (!pDeviceObjectEx->DeviceFileName)
164 {
165 free(pDeviceObjectEx->DeviceName);
166 free(pDeviceObjectEx);
167 return STATUS_NO_MEMORY;
168 }
169
170 if (winpr_PathFileExists(pDeviceObjectEx->DeviceFileName))
171 {
172 if (unlink(pDeviceObjectEx->DeviceFileName) == -1)
173 {
174 free(pDeviceObjectEx->DeviceName);
175 free(pDeviceObjectEx->DeviceFileName);
176 free(pDeviceObjectEx);
177 return STATUS_ACCESS_DENIED;
178 }
179 }
180
181 status = mkfifo(pDeviceObjectEx->DeviceFileName, 0666);
182
183 if (status != 0)
184 {
185 free(pDeviceObjectEx->DeviceName);
186 free(pDeviceObjectEx->DeviceFileName);
187 free(pDeviceObjectEx);
188
189 switch (errno)
190 {
191 case EACCES:
192 return STATUS_ACCESS_DENIED;
193
194 case EEXIST:
195 return STATUS_OBJECT_NAME_EXISTS;
196
197 case ENAMETOOLONG:
198 return STATUS_NAME_TOO_LONG;
199
200 case ENOENT:
201 case ENOTDIR:
202 return STATUS_NOT_A_DIRECTORY;
203
204 case ENOSPC:
205 return STATUS_DISK_FULL;
206
207 default:
208 return STATUS_INTERNAL_ERROR;
209 }
210 }
211
212 *((ULONG_PTR*)(DeviceObject)) = (ULONG_PTR)pDeviceObjectEx;
213 return STATUS_SUCCESS;
214}
215
221VOID _IoDeleteDeviceEx(PDEVICE_OBJECT_EX DeviceObject)
222{
223 DEVICE_OBJECT_EX* pDeviceObjectEx = NULL;
224 pDeviceObjectEx = (DEVICE_OBJECT_EX*)DeviceObject;
225
226 if (!pDeviceObjectEx)
227 return;
228
229 unlink(pDeviceObjectEx->DeviceFileName);
230 free(pDeviceObjectEx->DeviceName);
231 free(pDeviceObjectEx->DeviceFileName);
232 free(pDeviceObjectEx);
233}
234
235#endif