PHP ausgeführtes Programm endet erfolglos

  • PHP

    PHP ausgeführtes Programm endet erfolglos

    Hallo zusammen,

    ich würde gerne ein C++-Programm mit meinem PHP-Backend starten(mit exec()). Das C++-Programm ist zum sicheren Entfernen von USB-Sticks von meinem PC. Wenn ich das Programm (welches auf einem seperaten Lokalen Datenträger liegt) mit der CMD und ohne admin-Rechte ausführe, dann startet die Anwednung und gibt mir auch eine korrekte Ausgabe.

    C++-Quellcode:

    C-Quellcode

    1. //
    2. // RemoveDriveByLetter.cpp by Uwe Sieber - www.uwe-sieber.de
    3. //
    4. // Simple demonstration how to prepare a disk drive for save removal
    5. //
    6. // Works with removable and fixed drives under W2K, XP, W2K3, Vista
    7. //
    8. // Console application - expects the drive letter of the drive to remove as parameter
    9. //
    10. // you are free to use this code in your projects
    11. //
    12. #include "stdafx.h"
    13. #include <stdio.h>
    14. #include <windows.h>
    15. #include <Setupapi.h>
    16. #include <winioctl.h>
    17. #include <winioctl.h>
    18. #include <cfgmgr32.h>
    19. #include <string>
    20. //-------------------------------------------------
    21. DEVINST GetDrivesDevInstByDeviceNumber(long DeviceNumber, UINT DriveType, char* szDosDeviceName);
    22. //-------------------------------------------------
    23. //-------------------------------------------------
    24. int main(int argc, char* argv[])
    25. {
    26. /*if ( argc != 2 ) {
    27. return 1;
    28. }*/
    29. char DriveLetter = argv[1][0];
    30. DriveLetter &= ~0x20; // uppercase
    31. if ( DriveLetter < 'A' || DriveLetter > 'Z' ) {
    32. return 1;
    33. }
    34. std::string path = "";
    35. path += DriveLetter;
    36. path.append(":\\");
    37. printf(path.c_str());
    38. char szRootPath[sizeof(path)] ="";
    39. strncpy(szRootPath, path.c_str(), sizeof(path));
    40. std::string device = "";
    41. device += DriveLetter;
    42. device.append(":");
    43. printf(device.c_str());
    44. char szDevicePath[sizeof(device)] = "";
    45. strncpy(szDevicePath, device.c_str(), sizeof(device));
    46. std::string accesspath = "";
    47. accesspath += "\\\\.\\";
    48. accesspath += device;
    49. printf(accesspath.c_str());
    50. char szVolumeAccessPath[sizeof(accesspath)] = ""; // "\\.\X:" -> to open the volume
    51. strncpy(szVolumeAccessPath, accesspath.c_str(), sizeof(accesspath));
    52. long DeviceNumber = -1;
    53. // open the storage volume
    54. HANDLE hVolume = CreateFile(szVolumeAccessPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
    55. if (hVolume == INVALID_HANDLE_VALUE) {
    56. return 1;
    57. }
    58. // get the volume's device number
    59. STORAGE_DEVICE_NUMBER sdn;
    60. DWORD dwBytesReturned = 0;
    61. long res = DeviceIoControl(hVolume, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
    62. if ( res ) {
    63. DeviceNumber = sdn.DeviceNumber;
    64. }
    65. CloseHandle(hVolume);
    66. if ( DeviceNumber == -1 ) {
    67. return 1;
    68. }
    69. // get the drive type which is required to match the device numbers correctely
    70. UINT DriveType = GetDriveType(szRootPath);
    71. // get the dos device name (like \device\floppy0) to decide if it's a floppy or not - who knows a better way?
    72. char szDosDeviceName[MAX_PATH];
    73. res = QueryDosDevice(szDevicePath, szDosDeviceName, MAX_PATH);
    74. if ( !res ) {
    75. return 1;
    76. }
    77. // get the device instance handle of the storage volume by means of a SetupDi enum and matching the device number
    78. DEVINST DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber, DriveType, szDosDeviceName);
    79. if ( DevInst == 0 ) {
    80. return 1;
    81. }
    82. PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
    83. WCHAR VetoNameW[MAX_PATH];
    84. VetoNameW[0] = 0;
    85. bool bSuccess = false;
    86. // get drives's parent, e.g. the USB bridge, the SATA port, an IDE channel with two drives!
    87. DEVINST DevInstParent = 0;
    88. res = CM_Get_Parent(&DevInstParent, DevInst, 0);
    89. for ( long tries=1; tries<=3; tries++ ) { // sometimes we need some tries...
    90. VetoNameW[0] = 0;
    91. // CM_Query_And_Remove_SubTree doesn't work for restricted users
    92. //res = CM_Query_And_Remove_SubTreeW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, CM_REMOVE_NO_RESTART); // CM_Query_And_Remove_SubTreeA is not implemented under W2K!
    93. //res = CM_Query_And_Remove_SubTreeW(DevInstParent, NULL, NULL, 0, CM_REMOVE_NO_RESTART); // with messagebox (W2K, Vista) or balloon (XP)
    94. res = CM_Request_Device_EjectW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, 0);
    95. //res = CM_Request_Device_EjectW(DevInstParent, NULL, NULL, 0, 0); // with messagebox (W2K, Vista) or balloon (XP)
    96. bSuccess = (res==CR_SUCCESS && VetoType==PNP_VetoTypeUnknown);
    97. if ( bSuccess ) {
    98. break;
    99. }
    100. Sleep(500); // required to give the next tries a chance!
    101. }
    102. if ( bSuccess ) {
    103. printf("Success\n\n");
    104. return 0;
    105. }
    106. printf("failed\n");
    107. printf("Result=0x%2X\n", res);
    108. if ( VetoNameW[0] ) {
    109. printf("VetoName=%ws)\n\n", VetoNameW);
    110. }
    111. return 1;
    112. }
    113. //-----------------------------------------------------------
    114. char* appendCharToCharArray(char* array, char a)
    115. {
    116. size_t len = strlen(array);
    117. char* ret = new char[len+2];
    118. strcpy(ret, array);
    119. ret[len] = a;
    120. ret[len+1] = '\0';
    121. return ret;
    122. }
    123. //----------------------------------------------------------------------
    124. // returns the device instance handle of a storage volume or 0 on error
    125. //----------------------------------------------------------------------
    126. DEVINST GetDrivesDevInstByDeviceNumber(long DeviceNumber, UINT DriveType, char* szDosDeviceName)
    127. {
    128. bool IsFloppy = (strstr(szDosDeviceName, "\\Floppy") != NULL); // who knows a better way?
    129. GUID* guid;
    130. switch (DriveType) {
    131. case DRIVE_REMOVABLE:
    132. if ( IsFloppy ) {
    133. guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY;
    134. } else {
    135. guid = (GUID*)&GUID_DEVINTERFACE_DISK;
    136. }
    137. break;
    138. case DRIVE_FIXED:
    139. guid = (GUID*)&GUID_DEVINTERFACE_DISK;
    140. break;
    141. case DRIVE_CDROM:
    142. guid = (GUID*)&GUID_DEVINTERFACE_CDROM;
    143. break;
    144. default:
    145. return 0;
    146. }
    147. // Get device interface info set handle for all devices attached to system
    148. HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    149. if (hDevInfo == INVALID_HANDLE_VALUE) {
    150. return 0;
    151. }
    152. // Retrieve a context structure for a device interface of a device information set
    153. DWORD dwIndex = 0;
    154. long res;
    155. BYTE Buf[1024];
    156. PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
    157. SP_DEVICE_INTERFACE_DATA spdid;
    158. SP_DEVINFO_DATA spdd;
    159. DWORD dwSize;
    160. spdid.cbSize = sizeof(spdid);
    161. while ( true ) {
    162. res = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, dwIndex, &spdid);
    163. if ( !res ) {
    164. break;
    165. }
    166. dwSize = 0;
    167. SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL); // check the buffer size
    168. if ( dwSize!=0 && dwSize<=sizeof(Buf) ) {
    169. pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!
    170. ZeroMemory(&spdd, sizeof(spdd));
    171. spdd.cbSize = sizeof(spdd);
    172. long res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, &spdd);
    173. if ( res ) {
    174. // in case you are interested in the USB serial number:
    175. // the device id string contains the serial number if the device has one,
    176. // otherwise a generated id that contains the '&' char...
    177. /*
    178. DEVINST DevInstParent = 0;
    179. CM_Get_Parent(&DevInstParent, spdd.DevInst, 0);
    180. char szDeviceIdString[MAX_PATH];
    181. CM_Get_Device_ID(DevInstParent, szDeviceIdString, MAX_PATH, 0);
    182. printf("DeviceId=%s\n", szDeviceIdString);
    183. */
    184. // open the disk or cdrom or floppy
    185. HANDLE hDrive = CreateFile(pspdidd->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    186. if ( hDrive != INVALID_HANDLE_VALUE ) {
    187. // get its device number
    188. STORAGE_DEVICE_NUMBER sdn;
    189. DWORD dwBytesReturned = 0;
    190. res = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
    191. if ( res ) {
    192. if ( DeviceNumber == (long)sdn.DeviceNumber ) { // match the given device number with the one of the current device
    193. CloseHandle(hDrive);
    194. SetupDiDestroyDeviceInfoList(hDevInfo);
    195. return spdd.DevInst;
    196. }
    197. }
    198. CloseHandle(hDrive);
    199. }
    200. }
    201. }
    202. dwIndex++;
    203. }
    204. SetupDiDestroyDeviceInfoList(hDevInfo);
    205. return 0;
    206. }
    207. //-----------------------------------------------------------


    Aber wenn ich das Programm mit exec("/path/to/my/program.exe and-parameters") starte, was ja derselbe Aufruf ist wie mit der CMD, dann läuft die Anwendung zwar aber returnt "failed" also muss ja irgendwas anders ablaufen als bei dem Versuch mit der CMD.

    Ich benutze einen IIS als server und der hat auch volle Zugriffsrechte auf das zugrunde liegende Verzeichnis und Unterordner.

    Jemand eine Idee?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Goldwing Studios“ ()