ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

deviceio.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.