Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendeviceio.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: kernel32/file/deviceio.c 00005 * PURPOSE: Device I/O Base Client Functionality 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <k32.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* FUNCTIONS ******************************************************************/ 00016 00017 VOID 00018 WINAPI 00019 NotifySoundSentry(VOID) 00020 { 00021 CSR_API_MESSAGE ApiMessage; 00022 00023 /* Get the video mode */ 00024 if (!GetConsoleDisplayMode(&ApiMessage.Data.SoundSentryRequest.VideoMode)) 00025 { 00026 ApiMessage.Data.SoundSentryRequest.VideoMode = 0; 00027 } 00028 00029 /* Make sure it's not fullscreen, and send the message if not */ 00030 if (ApiMessage.Data.SoundSentryRequest.VideoMode == 0) 00031 { 00032 CsrClientCallServer(&ApiMessage, 00033 NULL, 00034 MAKE_CSR_API(SOUND_SENTRY, CSR_NATIVE), 00035 sizeof(CSR_API_MESSAGE)); 00036 } 00037 } 00038 00039 /* 00040 * @implemented 00041 */ 00042 BOOL 00043 WINAPI 00044 Beep(IN DWORD dwFreq, 00045 IN DWORD dwDuration) 00046 { 00047 HANDLE hBeep; 00048 UNICODE_STRING BeepDevice; 00049 OBJECT_ATTRIBUTES ObjectAttributes; 00050 IO_STATUS_BLOCK IoStatusBlock; 00051 BEEP_SET_PARAMETERS BeepSetParameters; 00052 NTSTATUS Status; 00053 00054 // 00055 // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen 00056 // after doing a GetProcAddress for it 00057 // 00058 00059 /* Open the device */ 00060 RtlInitUnicodeString(&BeepDevice, L"\\Device\\Beep"); 00061 InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL); 00062 Status = NtCreateFile(&hBeep, 00063 FILE_READ_DATA | FILE_WRITE_DATA, 00064 &ObjectAttributes, 00065 &IoStatusBlock, 00066 NULL, 00067 0, 00068 FILE_SHARE_READ | FILE_SHARE_WRITE, 00069 FILE_OPEN_IF, 00070 0, 00071 NULL, 00072 0); 00073 if (!NT_SUCCESS(Status)) 00074 { 00075 BaseSetLastNTError(Status); 00076 return FALSE; 00077 } 00078 00079 /* check the parameters */ 00080 if ((dwFreq >= 0x25 && dwFreq <= 0x7FFF) || 00081 (dwFreq == 0x0 && dwDuration == 0x0)) 00082 { 00083 /* Set beep data */ 00084 BeepSetParameters.Frequency = dwFreq; 00085 BeepSetParameters.Duration = dwDuration; 00086 00087 /* Send the beep */ 00088 Status = NtDeviceIoControlFile(hBeep, 00089 NULL, 00090 NULL, 00091 NULL, 00092 &IoStatusBlock, 00093 IOCTL_BEEP_SET, 00094 &BeepSetParameters, 00095 sizeof(BeepSetParameters), 00096 NULL, 00097 0); 00098 } 00099 else 00100 { 00101 /* We'll fail the call, but still notify the sound sentry */ 00102 Status = STATUS_INVALID_PARAMETER; 00103 } 00104 00105 /* Notify the sound sentry */ 00106 NotifySoundSentry(); 00107 00108 /* Bail out if the hardware beep failed */ 00109 if (!NT_SUCCESS(Status)) 00110 { 00111 NtClose(hBeep); 00112 BaseSetLastNTError(Status); 00113 return FALSE; 00114 } 00115 00116 /* If an actual beep was emitted, wait for it */ 00117 if (((dwFreq != 0x0) || (dwDuration != 0x0)) && (dwDuration != MAXDWORD)) 00118 { 00119 SleepEx(dwDuration, TRUE); 00120 } 00121 00122 /* Close the handle and return success */ 00123 NtClose(hBeep); 00124 return TRUE; 00125 } 00126 00127 /* 00128 * @implemented 00129 */ 00130 BOOL 00131 WINAPI 00132 DeviceIoControl(IN HANDLE hDevice, 00133 IN DWORD dwIoControlCode, 00134 IN LPVOID lpInBuffer OPTIONAL, 00135 IN DWORD nInBufferSize OPTIONAL, 00136 OUT LPVOID lpOutBuffer OPTIONAL, 00137 IN DWORD nOutBufferSize OPTIONAL, 00138 OUT LPDWORD lpBytesReturned OPTIONAL, 00139 IN LPOVERLAPPED lpOverlapped OPTIONAL) 00140 { 00141 BOOL FsIoCtl; 00142 NTSTATUS Status; 00143 PVOID ApcContext; 00144 IO_STATUS_BLOCK Iosb; 00145 00146 // 00147 // Note: on a TS Machine, we should call IsTSAppCompatEnabled and unless the 00148 // IOCTLs are IOCTL_STORAGE_EJECT_MEDIA, IOCTL_DISK_EJECT_MEDIA, FSCTL_DISMOUNT_VOLUME 00149 // we should call IsCallerAdminOrSystem and return STATUS_ACCESS_DENIED for 00150 // any other IOCTLs. 00151 // 00152 00153 /* Check what kind of IOCTL to send */ 00154 FsIoCtl = ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM); 00155 00156 /* CHeck for async */ 00157 if (lpOverlapped != NULL) 00158 { 00159 /* Set pending status */ 00160 lpOverlapped->Internal = STATUS_PENDING; 00161 00162 /* Check if there's an APC context */ 00163 ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); 00164 00165 /* Send file system control? */ 00166 if (FsIoCtl) 00167 { 00168 /* Send it */ 00169 Status = NtFsControlFile(hDevice, 00170 lpOverlapped->hEvent, 00171 NULL, 00172 ApcContext, 00173 (PIO_STATUS_BLOCK)lpOverlapped, 00174 dwIoControlCode, 00175 lpInBuffer, 00176 nInBufferSize, 00177 lpOutBuffer, 00178 nOutBufferSize); 00179 } 00180 else 00181 { 00182 /* Otherwise send a device control */ 00183 Status = NtDeviceIoControlFile(hDevice, 00184 lpOverlapped->hEvent, 00185 NULL, 00186 ApcContext, 00187 (PIO_STATUS_BLOCK)lpOverlapped, 00188 dwIoControlCode, 00189 lpInBuffer, 00190 nInBufferSize, 00191 lpOutBuffer, 00192 nOutBufferSize); 00193 } 00194 00195 /* Check for or information instead of failure */ 00196 if (!(NT_ERROR(Status)) && (lpBytesReturned)) 00197 { 00198 /* Protect with SEH */ 00199 _SEH2_TRY 00200 { 00201 /* Return the bytes */ 00202 *lpBytesReturned = lpOverlapped->InternalHigh; 00203 } 00204 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00205 { 00206 /* Return zero bytes */ 00207 *lpBytesReturned = 0; 00208 } 00209 _SEH2_END; 00210 } 00211 00212 /* Now check for any kind of failure except pending*/ 00213 if (!(NT_SUCCESS(Status)) || (Status == STATUS_PENDING)) 00214 { 00215 /* Fail */ 00216 BaseSetLastNTError(Status); 00217 return FALSE; 00218 } 00219 } 00220 else 00221 { 00222 /* Sync case -- send file system code? */ 00223 if (FsIoCtl) 00224 { 00225 /* Do it */ 00226 Status = NtFsControlFile(hDevice, 00227 NULL, 00228 NULL, 00229 NULL, 00230 &Iosb, 00231 dwIoControlCode, 00232 lpInBuffer, 00233 nInBufferSize, 00234 lpOutBuffer, 00235 nOutBufferSize); 00236 } 00237 else 00238 { 00239 /* Send device code instead */ 00240 Status = NtDeviceIoControlFile(hDevice, 00241 NULL, 00242 NULL, 00243 NULL, 00244 &Iosb, 00245 dwIoControlCode, 00246 lpInBuffer, 00247 nInBufferSize, 00248 lpOutBuffer, 00249 nOutBufferSize); 00250 } 00251 00252 /* Now check if the operation isn't done yet */ 00253 if (Status == STATUS_PENDING) 00254 { 00255 /* Wait for it and get the final status */ 00256 Status = NtWaitForSingleObject(hDevice, FALSE, NULL); 00257 if (NT_SUCCESS(Status)) Status = Iosb.Status; 00258 } 00259 00260 /* Check for success */ 00261 if (NT_SUCCESS(Status)) 00262 { 00263 /* Return the byte count */ 00264 *lpBytesReturned = Iosb.Information; 00265 } 00266 else 00267 { 00268 /* Check for informational or warning failure */ 00269 if (!NT_ERROR(Status)) *lpBytesReturned = Iosb.Information; 00270 00271 /* Return a failure */ 00272 BaseSetLastNTError(Status); 00273 return FALSE; 00274 } 00275 } 00276 00277 /* Return success */ 00278 return TRUE; 00279 } 00280 00281 /* 00282 * @implemented 00283 */ 00284 BOOL 00285 WINAPI 00286 CancelIo(IN HANDLE hFile) 00287 { 00288 IO_STATUS_BLOCK IoStatusBlock; 00289 NTSTATUS Status; 00290 00291 Status = NtCancelIoFile(hFile, &IoStatusBlock); 00292 if (!NT_SUCCESS(Status)) 00293 { 00294 BaseSetLastNTError(Status); 00295 return FALSE; 00296 } 00297 00298 return TRUE; 00299 } 00300 00301 /* EOF */ Generated on Sat May 26 2012 04:22:57 for ReactOS by
1.7.6.1
|