/* #FN# Performs special processing when the dialog box is initialized */ BOOL /* #AS# TRUE unless you set the focus to a control */ CTapeDlg:: OnInitDialog() { CCommonDlg::OnInitDialog(); /* Cache the kernel values */ _strncpy( m_szTapeFile, cassette_filename, FILENAME_MAX - 1 ); /* Backup a current tape file name and position */ _strncpy( m_szTapeBack, cassette_filename, FILENAME_MAX - 1 ); _strncpy( m_szTapeLast, cassette_filename, FILENAME_MAX - 1 ); m_nCurrentBack = cassette_current_block; /* Check if the tape image is a cassette file */ UINT unFileType = IAF_CAS_IMAGE; m_bCasImage = IsAtariFile( m_szTapeFile, &unFileType ); /* Cache some descriptions */ _LoadStringSx( IDS_TAPE_NO_CAS_IMAGE, m_szLabels[ LABEL_NOCASIMAGE ] ); _LoadStringSx( IDS_TAPE_NO_TAPE, m_szLabels[ LABEL_NOTAPE ] ); _LoadStringSx( IDS_TAPE_END_OF_TAPE, m_szLabels[ LABEL_ENDOFTAPE ] ); _LoadStringSx( IDS_TAPE_BLOCK_NO, m_szLabels[ LABEL_BLOCKNO ] ); _LoadStringSx( IDS_TAPE_EMPTY_TAPE, m_szLabels[ LABEL_EMPTYTAPE ] ); SetDlgState(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } /* #OF# CTapeDlg::OnInitDialog */
/* * supQueryTypeInfo * * Purpose: * * Query specific type info for output in listview. * */ BOOL supQueryTypeInfo( _In_ LPWSTR lpTypeName, _Inout_ LPWSTR Buffer, _In_ DWORD ccBuffer //size of buffer in chars ) { BOOL bResult = FALSE; ULONG i, nPool; POBJECT_TYPE_INFORMATION pObject; if ((g_pObjectTypesInfo == NULL) || (Buffer == NULL) ) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return bResult; } if (ccBuffer < MAX_PATH) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return bResult; } pObject = (POBJECT_TYPE_INFORMATION)&g_pObjectTypesInfo->TypeInformation; for (i = 0; i < g_pObjectTypesInfo->NumberOfTypes; i++) { /* Warning: Dxgk objects missing in this enum in Windows 10 TP WCHAR test[1000]; RtlSecureZeroMemory(&test, sizeof(test)); wsprintfW(test, L"\nLength=%lx, MaxLen=%lx \n", pObject->TypeName.Length, pObject->TypeName.MaximumLength); OutputDebugString(test); _strncpy(test, MAX_PATH, pObject->TypeName.Buffer, pObject->TypeName.MaximumLength); OutputDebugString(test);*/ if (_strncmpi(pObject->TypeName.Buffer, lpTypeName, pObject->TypeName.Length / sizeof(WCHAR)) == 0) { for (nPool = 0; nPool < MAX_KNOWN_POOL_TYPES; nPool++) { if ((POOL_TYPE)pObject->PoolType == (POOL_TYPE)a_PoolTypes[nPool].dwValue) { _strncpy( Buffer, ccBuffer, a_PoolTypes[nPool].lpDescription, _strlen(a_PoolTypes[nPool].lpDescription) ); break; } } bResult = TRUE; } if (bResult) { break; } //next entry located after the aligned type name buffer pObject = (POBJECT_TYPE_INFORMATION)((PCHAR)(pObject + 1) + ALIGN_UP(pObject->TypeName.MaximumLength, sizeof(ULONG_PTR))); } return bResult; }
USHORT FAR prntf (NPSZ buf, NPSZ fmt, PUCHAR arg_ptr) { NPCH sptr; LONG lval; ULONG uval; fs.buf = buf; fs.off = 0; fs.fmtptr = fmt; while (process_format (&fs) != TYPE_END) { switch (fs.type) { case TYPE_STRING: sptr = va_arg (arg_ptr, NPCH); put_field (&fs, sptr); break; case TYPE_CHAR: *(short far *)(fs.buf+fs.off) = va_arg (arg_ptr, USHORT); fs.off++; break; case TYPE_PCT: *(short far *)(fs.buf+fs.off) = '%'; fs.off++; break; case TYPE_DECIMAL: lval = (fs.flags & FS_LONG) ? va_arg (arg_ptr, LONG) : va_arg (arg_ptr, INT ); cvtld (sbuf, lval); put_field (&fs, sbuf); break; case TYPE_UNSIGNED: case TYPE_HEX: uval = (fs.flags & FS_LONG) ? va_arg (arg_ptr, ULONG) : va_arg (arg_ptr, USHORT ); if (fs.type == TYPE_HEX) cvtlx (sbuf, uval); else cvtlu (sbuf, uval); put_field (&fs, sbuf); break; case TYPE_INVALID: _strncpy (fs.buf+fs.off, fs.fmtstrt, fs.fmtptr-fs.fmtstrt); fs.off += fs.fmtptr - fs.fmtstrt; break; } } return (0); }
int main(void) { char *t = "testring1234"; char *s; _strncpy(s, t, 8); printf("strncpy: %s\n", s); return 0; }
/* * supFindModuleEntryByAddress * * Purpose: * * Find Module Name for given Address. * */ BOOL supFindModuleEntryByAddress( _In_ CONST PRTL_PROCESS_MODULES pModulesList, _In_ PVOID Address, _Inout_ LPWSTR Buffer, _In_ DWORD ccBuffer //size of buffer in chars ) { ULONG i, c; PRTL_PROCESS_MODULE_INFORMATION pModule; WCHAR szBuffer[MAX_PATH + 1]; if ( (Address == NULL) || (pModulesList == NULL) || (Buffer == NULL) || (ccBuffer == 0) ) { return FALSE; } c = pModulesList->NumberOfModules; if (c == 0) { return FALSE; } for (i = 0; i < c; i++) { if ( IN_REGION(Address, pModulesList->Modules[i].ImageBase, pModulesList->Modules[i].ImageSize) ) { pModule = &pModulesList->Modules[i]; RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); if ( MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&pModule->FullPathName[pModule->OffsetToFileName], sizeof(pModule->FullPathName), szBuffer, MAX_PATH) ) { _strncpy(Buffer, ccBuffer, szBuffer, _strlen(szBuffer)); return TRUE; } else { //MultiByteToWideChar error return FALSE; } } } return FALSE; }
/* #FN# Performs special processing when the dialog box is initialized */ BOOL /* #AS# TRUE unless you set the focus to a control */ CKeyboardDlg:: OnInitDialog() { CCommonDlg::OnInitDialog(); m_ulInputState = g_Input.ulState; m_nArrowsMode = g_Input.Key.nArrowsMode; _strncpy( m_szTemplateFile, g_szTemplateFile, MAX_PATH ); _strncpy( m_szTemplateDesc, g_szTemplateDesc, TEMPLATE_DESC_LENGTH ); /* Read the template from a file */ PrepareTemplate( m_szTemplateFile, m_szTemplateDesc ); SetDlgState(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } /* #OF# CKeyboardDlg::OnInitDialog */
/* #FN# Prepares the tape to be accessed or removed */ BOOL /* #AS# Nothing */ CTapeDlg:: PrepareTape( LPSTR pszTapeFile, BOOL bCheckIfExists /*=TRUE*/, BOOL bForceInsert /*=FALSE*/ ) { BOOL bResult = FALSE; if( _IsPathAvailable( pszTapeFile ) ) { CFileStatus fsStatus; if( !bCheckIfExists || CFile::GetStatus( pszTapeFile, fsStatus ) ) { UINT unFileType = IAF_CAS_IMAGE; m_bCasImage = IsAtariFile( pszTapeFile, &unFileType ); bForceInsert = bForceInsert || m_bCasImage || _stricmp( m_szTapeLast, pszTapeFile ) == 0; if( bForceInsert || DisplayWarning( IDS_WARN_CASFILE, DONT_SHOW_CASFILE_WARN, TRUE ) ) { /* Prevents from resource leaks */ CASSETTE_Remove(); /* We have to attach a selected file because there is need to update some kernel-depending cassette parameters */ if( CASSETTE_Insert( pszTapeFile ) ) { /* A tape image has been properly inserted */ bResult = TRUE; } else DisplayMessage( GetSafeHwnd(), IDS_ERROR_CAS_READ, 0, MB_ICONEXCLAMATION | MB_OK ); } } } /* It is a good idea to remove the tape if no success */ if( !bResult ) EjectTape(); /* Save a name of the last used image */ _strncpy( m_szTapeLast, pszTapeFile, FILENAME_MAX - 1 ); return bResult; } /* #OF# CTapeDlg::PrepareTape */
/* * FindDlgAddTypes * * Purpose: * * Enumerate object types and fill combobox with them. * */ VOID FindDlgAddTypes( HWND hwnd ) { ULONG i; HWND hComboBox; SIZE_T sz; LPWSTR lpType; POBJECT_TYPE_INFORMATION pObject; hComboBox = GetDlgItem(hwnd, ID_SEARCH_TYPE); if (hComboBox == NULL) { return; } SendMessage(hComboBox, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); if (g_pObjectTypesInfo == NULL) { SendMessage(hComboBox, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"*"); SendMessage(hComboBox, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); return; } // // Warning: not all object types are listed. // __try { //type collection available, list it pObject = (POBJECT_TYPE_INFORMATION)&g_pObjectTypesInfo->TypeInformation; for (i = 0; i < g_pObjectTypesInfo->NumberOfTypes; i++) { sz = pObject->TypeName.MaximumLength + sizeof(UNICODE_NULL); lpType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz); if (lpType) { _strncpy(lpType, sz / sizeof(WCHAR), pObject->TypeName.Buffer, pObject->TypeName.Length / sizeof(WCHAR)); SendMessage(hComboBox, CB_ADDSTRING, (WPARAM)0, (LPARAM)lpType); HeapFree(GetProcessHeap(), 0, lpType); } pObject = (POBJECT_TYPE_INFORMATION)((PCHAR)(pObject + 1) + ALIGN_UP(pObject->TypeName.MaximumLength, sizeof(ULONG_PTR))); } SendMessage(hComboBox, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"*"); SendMessage(hComboBox, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } __except (exceptFilter(GetExceptionCode(), GetExceptionInformation())) { return; } }
/* #FN# Sets up tape position information */ void /* #AS# Nothing */ CTapeDlg:: SetPosInfo( UINT nPos /* #IN# Position of the tape slider */ ) { CWnd *pStatic = GetDlgItem( IDC_TAPE_POSITION ); ASSERT(NULL != pStatic); static char szInfo[ LOADSTRING_SIZE_S + 1 ]; if( cassette_max_block > 1 ) { if( (cassette_max_block + 1) == (int)nPos ) { /* Set the "End of tape" label */ _strncpy( szInfo, m_szLabels[ LABEL_ENDOFTAPE ], LOADSTRING_SIZE_S ); } else /* Set the "Block x of y" label */ sprintf( szInfo, m_szLabels[ LABEL_BLOCKNO ], nPos, cassette_max_block ); } else if( m_bCasImage ) { /* Set the "Empty tape" label */ _strncpy( szInfo, m_szLabels[ LABEL_EMPTYTAPE ], LOADSTRING_SIZE_S ); } else /* Set the "No tape attached" label */ _strncpy( szInfo, m_szLabels[ LABEL_NOTAPE ], LOADSTRING_SIZE_S ); pStatic->SetWindowText( szInfo ); } /* #OF# CTapeDlg::SetPosInfo */
int main(void) { char a[] = "Hello world\n"; char *p = a; int i = 0; while (p[i] != '\0') { printf("%c", p[i]); i++; } /* The source string can be const string ie, char * because we are only * going to iterate over the string. The destination has to be a char * array or a pointer to malloc array, ie, it should have the required * amount of memory available with it because the data is going to be * copied to its location */ char *s = "Hello"; char t[6]; _strncpy(s, t, 1); printf("%s\n", t); s = "World"; /* Char * can point to a new location because the pointer * wasn't a const, only the string was. */ /* Testing with malloc'd block of data. We need to use strlen on char * * to get the string size. sizeof will give the size of pointer. Also * strlen gives length by ignoring \0, we need additional space for that * as well, thus the +1 */ char *mp = (char *)malloc(strlen(s) + 1); _strcpy(s, mp); printf("%s\n", mp); char big[12] = "Hello"; char *small = " World"; _strcat(big, small); printf("Concat: %s\n", big); struct mystruct m = { .c = 'c', .n = 42, .f = 3.14, }; printf("%u is the offset of char\n", _offset_of(struct mystruct, c)); printf("%u is the offset of int\n", _offset_of(struct mystruct, n)); printf("%u is the offset of float\n", _offset_of(struct mystruct, f)); printf("%u is the size\n", sizeof(struct mystruct)); }
/* #FN# Displays New Tape Image dialog box */ void /* #AS# Nothing */ CTapeDlg:: OnNewImage() { CNewTapeImageDlg dlgNewTapeImage; if( IDOK == dlgNewTapeImage.DoModal() && /* Attach tape image to the tape recorder if it was expected */ dlgNewTapeImage.m_bAttachTape ) { /* Set a name of the created image */ _strncpy( m_szTapeFile, dlgNewTapeImage.m_szTapeName, FILENAME_MAX - 1 ); SetDlgItemText( IDC_TAPE_FILE, m_szTapeFile ); /* Open a tape image */ PrepareTape( m_szTapeFile, FALSE, TRUE ); SetDlgState(); } } /* #OF# CTapeDlg::OnNewImage */
/* * supQueryProcessName * * Purpose: * * Lookups process name by given process ID. * * If nothing found return FALSE. * */ BOOL supQueryProcessName( _In_ DWORD dwProcessId, _In_ PVOID ProcessList, _Inout_ LPWSTR Buffer, _In_ DWORD ccBuffer //size of buffer in chars ) { PSYSTEM_PROCESSES_INFORMATION pList = ProcessList; if ((ProcessList == NULL) || (Buffer == NULL) || (ccBuffer == 0)) return FALSE; for (;;) { if ((DWORD)pList->UniqueProcessId == dwProcessId) { _strncpy(Buffer, ccBuffer, pList->ImageName.Buffer, pList->ImageName.Length / sizeof(WCHAR)); return TRUE; } if (pList->NextEntryDelta == 0) break; pList = (PSYSTEM_PROCESSES_INFORMATION)(((LPBYTE)pList) + pList->NextEntryDelta); } return FALSE; }
static void _setup (void) { struct hostent *hptr; char *temp; if (signal (SIGINT, _signal_handler) == SIG_ERR) ipmi_ping_err_exit ("signal setup failed"); if ((pingtool_sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) ipmi_ping_err_exit ("socket: %s", strerror (errno)); memset (&pingtool_srcaddr, '\0', sizeof (pingtool_srcaddr)); pingtool_srcaddr.sin_family = AF_INET; pingtool_srcaddr.sin_port = htons (0); if (!pingtool_interface) pingtool_srcaddr.sin_addr.s_addr = htonl (INADDR_ANY); else { /* If there is a period, assume user input an IP address. No * period, assume user input an interface name */ if (strchr (pingtool_interface, '.')) { int rv; if ((rv = inet_pton (AF_INET, pingtool_interface, &pingtool_srcaddr.sin_addr)) < 0) ipmi_ping_err_exit ("inet_pton: %s", strerror (errno)); if (!rv) ipmi_ping_err_exit ("invalid interface address"); } else { struct ifreq ifr; struct sockaddr_in temp_sockaddr; _strncpy (ifr.ifr_name, pingtool_interface, IFNAMSIZ); ifr.ifr_addr.sa_family = AF_INET; if (ioctl (pingtool_sockfd, SIOCGIFADDR, &ifr) < 0) ipmi_ping_err_exit ("ioctl: %s", strerror (errno)); temp_sockaddr = *((struct sockaddr_in *)&ifr.ifr_addr); memcpy (&pingtool_srcaddr.sin_addr.s_addr, &temp_sockaddr.sin_addr.s_addr, sizeof (pingtool_srcaddr.sin_addr.s_addr)); } } if (bind (pingtool_sockfd, (struct sockaddr *)&pingtool_srcaddr, sizeof (pingtool_srcaddr)) < 0) ipmi_ping_err_exit ("bind: %s", strerror (errno)); memset (&pingtool_destaddr, '\0', sizeof (pingtool_destaddr)); pingtool_destaddr.sin_family = AF_INET; pingtool_destaddr.sin_port = htons (RMCP_PRIMARY_RMCP_PORT); if (!(hptr = gethostbyname (pingtool_dest))) { #if HAVE_HSTRERROR ipmi_ping_err_exit ("gethostbyname: %s", hstrerror (h_errno)); #else /* !HAVE_HSTRERROR */ ipmi_ping_err_exit ("gethostbyname: h_errno = %d", h_errno); #endif /* !HAVE_HSTRERROR */ } pingtool_destaddr.sin_addr = *((struct in_addr *)hptr->h_addr); temp = inet_ntoa (pingtool_destaddr.sin_addr); _strncpy (pingtool_dest_ip, temp, INET_ADDRSTRLEN); srand (time (NULL)); }
static void _cmdline_parse (int argc, char **argv, unsigned int min_sequence_number, unsigned int max_sequence_number, const char *options) { char *endptr; int c; assert (argc >= 0); assert (argv); /* Turn off error messages */ opterr = 0; while ((c = getopt (argc, argv, options)) != -1) { switch (c) { case 'h': _output_usage (options); case 'V': _output_version (); case 'r': if (!strcmp (optarg, IPMI_PING_VERSION_1_5_STR)) pingtool_version = IPMI_PING_VERSION_1_5; else if (!strcmp (optarg, IPMI_PING_VERSION_2_0_STR)) pingtool_version = IPMI_PING_VERSION_2_0; else ipmi_ping_err_exit ("invalid version"); break; case 'c': errno = 0; pingtool_count = strtol (optarg, &endptr, 10); if (errno || endptr[0] != '\0') ipmi_ping_err_exit ("count argument invalid"); if (!pingtool_count) ipmi_ping_err_exit ("count must be > 0"); break; case 'i': errno = 0; pingtool_interval = strtol (optarg, &endptr, 10); if (errno || endptr[0] != '\0') ipmi_ping_err_exit ("interval argument invalid"); if (!pingtool_interval) ipmi_ping_err_exit ("interval must be > 0"); break; case 'I': pingtool_interface = optarg; break; case 't': errno = 0; pingtool_timeout = strtol (optarg, &endptr, 10); if (errno || endptr[0] != '\0') ipmi_ping_err_exit ("timeout argument invalid"); if (!pingtool_timeout) ipmi_ping_err_exit ("timeout must be > 0"); break; case 'v': pingtool_verbose++; break; case 's': errno = 0; pingtool_initial_sequence_number = strtol (optarg, &endptr, 10); if (errno || endptr[0] != '\0') ipmi_ping_err_exit ("initial sequence number invalid"); if (pingtool_initial_sequence_number < min_sequence_number || pingtool_initial_sequence_number > max_sequence_number) ipmi_ping_err_exit ("initial sequence number out of range"); break; case 'd': pingtool_debug++; break; default: ipmi_ping_err_exit ("Command line option error"); break; } } /* last argument is destination */ if (optind >= argc) ipmi_ping_err_exit ("destination must be specified"); _strncpy (pingtool_dest, argv[optind], MAXHOSTNAMELEN); }
/* * propCreateDialog * * Purpose: * * Initialize and create PropertySheet Window * * Sets custom Window Procedure for PropertySheet * */ VOID propCreateDialog( _In_ HWND hwndParent, _In_ LPWSTR lpObjectName, _In_ LPCWSTR lpObjectType, _In_opt_ LPWSTR lpDescription ) { INT nPages; HWND hwndDlg; PROP_OBJECT_INFO *propContext = NULL; HPROPSHEETPAGE SecurityPage; PROPSHEETPAGE Page; PROPSHEETHEADER PropHeader; WCHAR szCaption[MAX_PATH * 2]; if ((hwndParent == NULL) || (lpObjectName == NULL) || (lpObjectType == NULL)) { return; } // //allocate context variable, copy name, type, object path // propContext = propContextCreate(lpObjectName, lpObjectType, CurrentObjectPath, lpDescription); if (propContext == NULL) { return; } //if worker available - wait on it if (g_kdctx.hDevice) { if (g_kdctx.hThreadWorker) { WaitForSingleObject(g_kdctx.hThreadWorker, INFINITE); CloseHandle(g_kdctx.hThreadWorker); g_kdctx.hThreadWorker = NULL; } } //remember previously focused window //except special types: desktop if (propContext->TypeIndex != TYPE_DESKTOP) { hPrevFocus = GetFocus(); } //zero pages arrays nPages = 0; RtlSecureZeroMemory(psp, sizeof(psp)); // // Properties: // Basic->[Object]->[Process]->[Desktops]->[Registry]->Type->[Security] // // //Basic Info Page // RtlSecureZeroMemory(&Page, sizeof(Page)); Page.dwSize = sizeof(PROPSHEETPAGE); Page.dwFlags = PSP_DEFAULT | PSP_USETITLE; Page.hInstance = g_hInstance; //select dialog for basic info switch (propContext->TypeIndex) { case TYPE_TIMER: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_TIMER); break; case TYPE_MUTANT: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_MUTANT); break; case TYPE_SEMAPHORE: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_SEMAPHORE); break; case TYPE_JOB: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_JOB); break; case TYPE_WINSTATION: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_WINSTATION); break; case TYPE_EVENT: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_EVENT); break; case TYPE_SYMLINK: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_SYMLINK); break; case TYPE_KEY: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_KEY); break; case TYPE_SECTION: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_SECTION); break; case TYPE_DRIVER: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_DRIVER); break; case TYPE_DEVICE: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_DEVICE); break; case TYPE_IOCOMPLETION: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_IOCOMPLETION); break; case TYPE_TYPE: default: Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_BASIC); break; } Page.pfnDlgProc = BasicPropDialogProc; Page.pszTitle = L"Basic"; Page.lParam = (LPARAM)propContext; psp[nPages++] = CreatePropertySheetPage(&Page); // //Create Objects page for supported types // if (g_kdctx.hDevice != NULL) { switch (propContext->TypeIndex) { case TYPE_DIRECTORY: case TYPE_DRIVER: case TYPE_DEVICE: case TYPE_EVENT: case TYPE_MUTANT: case TYPE_SEMAPHORE: case TYPE_TIMER: case TYPE_IOCOMPLETION: case TYPE_TYPE: RtlSecureZeroMemory(&Page, sizeof(Page)); Page.dwSize = sizeof(PROPSHEETPAGE); Page.dwFlags = PSP_DEFAULT | PSP_USETITLE; Page.hInstance = g_hInstance; Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_OBJECTDUMP); Page.pfnDlgProc = ObjectDumpDialogProc; Page.pszTitle = L"Object"; Page.lParam = (LPARAM)propContext; psp[nPages++] = CreatePropertySheetPage(&Page); break; } } // //Create additional page(s), depending on object type // switch (propContext->TypeIndex) { case TYPE_DIRECTORY: case TYPE_PORT: case TYPE_FLTCOMM_PORT: case TYPE_FLTCONN_PORT: case TYPE_EVENT: case TYPE_MUTANT: case TYPE_SEMAPHORE: case TYPE_SECTION: case TYPE_SYMLINK: case TYPE_TIMER: case TYPE_JOB: case TYPE_WINSTATION: case TYPE_IOCOMPLETION: RtlSecureZeroMemory(&Page, sizeof(Page)); Page.dwSize = sizeof(PROPSHEETPAGE); Page.dwFlags = PSP_DEFAULT | PSP_USETITLE; Page.hInstance = g_hInstance; Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_PROCESSLIST); Page.pfnDlgProc = ProcessListDialogProc; Page.pszTitle = L"Process"; Page.lParam = (LPARAM)propContext; psp[nPages++] = CreatePropertySheetPage(&Page); // //Add desktop list for selected desktop, located here because of sheets order // if (propContext->TypeIndex == TYPE_WINSTATION) { RtlSecureZeroMemory(&Page, sizeof(Page)); Page.dwSize = sizeof(PROPSHEETPAGE); Page.dwFlags = PSP_DEFAULT | PSP_USETITLE; Page.hInstance = g_hInstance; Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_DESKTOPS); Page.pfnDlgProc = DesktopListDialogProc; Page.pszTitle = L"Desktops"; Page.lParam = (LPARAM)propContext; psp[nPages++] = CreatePropertySheetPage(&Page); } break; case TYPE_DRIVER: // //Add registry page // RtlSecureZeroMemory(&Page, sizeof(Page)); Page.dwSize = sizeof(PROPSHEETPAGE); Page.dwFlags = PSP_DEFAULT | PSP_USETITLE; Page.hInstance = g_hInstance; Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_SERVICE); Page.pfnDlgProc = DriverRegistryDialogProc; Page.pszTitle = L"Registry"; Page.lParam = (LPARAM)propContext; psp[nPages++] = CreatePropertySheetPage(&Page); break; } // //Type Info Page // RtlSecureZeroMemory(&Page, sizeof(Page)); Page.dwSize = sizeof(PROPSHEETPAGE); Page.dwFlags = PSP_DEFAULT | PSP_USETITLE; Page.hInstance = g_hInstance; Page.pszTemplate = MAKEINTRESOURCE(IDD_PROP_TYPE); Page.pfnDlgProc = TypePropDialogProc; Page.pszTitle = L"Type"; Page.lParam = (LPARAM)propContext; psp[nPages++] = CreatePropertySheetPage(&Page); // //Create Security Dialog if available // SecurityPage = propSecurityCreatePage( propContext, //Context (POPENOBJECTMETHOD)&propOpenCurrentObject, //OpenObjectMethod NULL, //CloseObjectMethod, use default SI_EDIT_AUDITS | SI_EDIT_OWNER | SI_EDIT_PERMS | //psiFlags SI_ADVANCED | SI_NO_ACL_PROTECT | SI_NO_TREE_APPLY | SI_PAGE_TITLE ); if (SecurityPage != NULL) { psp[nPages++] = SecurityPage; } // //Finally create property sheet // if (propContext->IsType) { _strncpy(szCaption, MAX_PATH, lpObjectName, _strlen(lpObjectName)); } else { _strncpy(szCaption, MAX_PATH, lpObjectType, _strlen(lpObjectType)); } _strcat(szCaption, L" Properties"); RtlSecureZeroMemory(&PropHeader, sizeof(PropHeader)); PropHeader.dwSize = sizeof(PropHeader); PropHeader.phpage = psp; PropHeader.nPages = nPages; PropHeader.dwFlags = PSH_DEFAULT | PSH_NOCONTEXTHELP | PSH_MODELESS; PropHeader.nStartPage = 0; PropHeader.hwndParent = hwndParent; PropHeader.hInstance = g_hInstance; PropHeader.pszCaption = szCaption; hwndDlg = (HWND)PropertySheet(&PropHeader); //remove class icon if any SetClassLongPtr(hwndDlg, GCLP_HICON, (LONG_PTR)NULL); if (propContext->TypeIndex == TYPE_DESKTOP) { g_SubPropWindow = hwndDlg; } else { g_PropWindow = hwndDlg; } if (hwndDlg) { SetProp(hwndDlg, T_PROPCONTEXT, (HANDLE)propContext); PropSheetOriginalWndProc = (WNDPROC)GetWindowLongPtr(hwndDlg, GWLP_WNDPROC); if (PropSheetOriginalWndProc) { SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)&PropSheetCustomWndProc); } supCenterWindow(hwndDlg); } }
/* read a structure with controlled by whitespace/indentation */ int animenu_readmenufile(FILE *f, char ***item) { /* append valid lines to a dynamic buff buffer, determining the * max length and number of lines for the current config item. * allocate memory and then split when hitting the next item or eof * caller must free the memory allocation, and can use _freecfg */ int i; int idx = 0; /* item index */ int maxlen = 0; /* max length seen */ int maxlenline = BUFSIZE + 1; /* max line length */ int len; char s[maxlenline]; char *s2; char *b = malloc(maxlenline); /* flattened item buffer */ const char* rx_comment = "^\\s*#.*"; const char* rx_empty = "^\\s*$"; const char* rx_nested = "^\\s+.*"; struct animenu_options* options = get_options(); /* read item to buffer*/ b[0] = '\0'; do { s[0] = '\0'; if (!(fgets(s, maxlenline - 1, f))) { /* eof */ if (idx > 0) /* process final item */ break; else { /* nothing left to read */ free(b); return(FALSE); } } if (rx_compare(s, rx_empty) == 0 || rx_compare(s, rx_comment) == 0) continue; if (rx_compare(s, rx_nested) != 0) { if (idx > 0) { fseek(f, -strlen(s), SEEK_CUR); break; } } s2 = animenu_stripwhitespace(s); len = strlen(s2); maxlen = _max(len, maxlen); if (idx == 0) { /* force lower case 'type' */ for (i = 0; b[i]; i++) b[i] = tolower(b[i]); } if (strlen(s) + len + 1 > sizeof(s)) { /* enlarge buffer */ char *b2 = strdup(b); b = realloc(b, sizeof(b) + maxlenline); strcpy(b, b2); free(b2); } sprintf(b + strlen(b), "%s\n", s2); idx++; } while (1); /* create item from flat buffer */ (*item) = malloc(idx * sizeof(char*)); (*item)[0] = malloc(idx * (maxlen + 1) * sizeof(char)); int pos = 0; char *n = NULL; if (options->debug > 0) fprintf(stderr, "parsed config item:\n"); for (i = 0; pos < strlen(b); i++) { (*item)[i] = (*item)[0] + i * (maxlen + 1); n = strchr(b + pos, '\n'); _strncpy((*item)[i], b + pos, n - (b + pos) + 1); pos += n - (b + pos) + 1; if (options->debug > 0) fprintf(stderr, "[%d] %s\n", i, (*item)[i]); } free(b); return(TRUE); }
/* create filesystem menu content */ struct animenucontext *animenu_createfilesystem(char *path, char *regex, char *command, int recurse) { struct animenucontext *menu; struct animenuitem *item; DIR *d = NULL; struct stat statbuf; struct dirent *dirent; char *title, *commandall; char pathbase[BUFSIZE + 1], pathcur[BUFSIZE + 1]; unsigned int size; struct files { char file[PATH_MAX + 1]; struct files *next; } *filecur, *fileroot = NULL, *fileprev = NULL; if (path) /* path already set, so use that */ _strncpy(pathbase, path, BUFSIZE + 1); else { if (regex == NULL) { fprintf(stderr, "cannot set base path"); return(FALSE); } else if (*regex != '/') { fprintf(stderr, "cannot set base path from '%s', ensure it is fully qualified", regex); return(FALSE); } /* set base path */ _strncpy(pathbase, regex, BUFSIZE + 1); char *rxs; if (rx_start(pathbase, &rxs)) *rxs = '\0'; /* return pointer to last occurence of char in array * and use this to terminate the string */ *strrchr(pathbase, '/') = '\0'; } if (!(d = opendir(pathbase))) { fprintf(stderr, "invalid base path '%s'", pathbase); return(FALSE); } /* fail if we can't allocate enough memory for the menu struct (known size) */ if (!(menu = malloc(sizeof(struct animenucontext)))) return(FALSE); memset(menu, 0, sizeof(struct animenucontext)); /* function pointers */ menu->dispose = animenu_disposemenu; menu->next = animenu_next; menu->prev = animenu_prev; menu->show = animenu_show; menu->showcurrent = animenu_showcurrent; menu->hide = animenu_hide; menu->additem = animenu_additem; menu->firstitem = NULL; menu->currentitem = NULL; menu->osd = NULL; for (*pathcur = '\0'; (dirent = readdir(d));) { /* use 'back' navigation to move up through the file hierarchy instead */ if (!strcmp(dirent->d_name, "..") || !strcmp(dirent->d_name, ".")) continue; /* set 'cur' as the current full path for consideration */ snprintf(pathcur, BUFSIZE + 1, "%s/%s", pathbase, dirent->d_name); if (stat(pathcur, &statbuf) != -1) { if (S_ISREG(statbuf.st_mode)) { if (!rx_compare(pathcur, regex)) { /* match the regex path */ if (!(filecur = malloc(sizeof(struct files)))) continue; if (fileroot == NULL) fileroot = filecur; else fileprev->next = filecur; /* copy the path into the file struct's file variable */ _strncpy(filecur->file, pathcur, BUFSIZE + 1); filecur->next = NULL; fileprev = filecur; } } else if (S_ISDIR(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { if (recurse) ; /* no-op */ else { /* add the dir/link regardless of match */ if (!(filecur = malloc(sizeof(struct files)))) continue; if (fileroot == NULL) fileroot = filecur; else fileprev->next = filecur; /* copy the path into our struct's file variable */ _strncpy(filecur->file, pathcur, BUFSIZE + 1); filecur->next = NULL; fileprev = filecur; } } } } closedir(d); /* create the browse menu's items * either 'command' items or 'browse' (menu) items */ if (!*pathcur) { menu->dispose(menu); return(FALSE); } if (fileroot) { /* get the final size for the command + args string */ for (size = strlen(command) + 1, filecur = fileroot; filecur != NULL; filecur = filecur->next) size += strlen(filecur->file) + 3; if (!(commandall = malloc(size + 1))) { menu->dispose(menu); return(FALSE); } _strncpy(commandall, command, size); for (filecur = fileroot; filecur != NULL; filecur = filecur->next) { _strncat(commandall, " \"", size); _strncat(commandall, filecur->file, size); _strncat(commandall, "\"", size); } item = animenu_createitem(animenuitem_command, (char*)playall, NULL, NULL, commandall, 0); menu->additem(menu, item); for (filecur = fileroot; filecur != NULL; filecur = filecur->next) { title = strrchr(filecur->file, '/'); stat(filecur->file, &statbuf); if (S_ISREG(statbuf.st_mode)) { /* create command item */ snprintf(commandall, size, "%s \"%s\"", command, filecur->file); item = animenu_createitem(animenuitem_command, ++title, NULL, NULL, commandall, 0); menu->additem(menu, item); } else if (S_ISDIR(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { /* create menu item */ item = animenu_createitem(animenuitem_filesystem, title, filecur->file, regex, command, recurse); menu->additem(menu, item); } } } else { /* create empty item for empty menu */ item = animenu_createitem(animenuitem_null, NULL, NULL, NULL, NULL, 0); menu->additem(menu, item); } return(menu); }
/* * DriverSetInfo * * Purpose: * * Sets registry info for selected driver object * */ VOID DriverSetInfo( PROP_OBJECT_INFO *Context, HWND hwndDlg ) { BOOL cond = FALSE, bResult, fGroup, bRet; INT nEndOfList, nEnd, nStart; DWORD i, bytesNeeded, dwServices, dwGroups; LPWSTR lpType; SC_HANDLE SchSCManager; SC_HANDLE schService; LPENUM_SERVICE_STATUS lpDependencies = NULL; LPQUERY_SERVICE_CONFIG psci; LPSERVICE_DESCRIPTION psd; SERVICE_STATUS_PROCESS ssp; ENUM_SERVICE_STATUS ess; WCHAR szBuffer[MAX_PATH + 1]; if (Context == NULL) { ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), TRUE); return; } __try { ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), FALSE); psci = NULL; SchSCManager = NULL; bResult = FALSE; do { SchSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); if (SchSCManager == NULL) { break; } schService = OpenService(SchSCManager, Context->lpObjectName, SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); if (schService == NULL) { break; } bytesNeeded = 0; bResult = QueryServiceConfig(schService, NULL, 0, &bytesNeeded); if ((bResult == FALSE) && (bytesNeeded == 0)) { break; } psci = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (psci == NULL) { break; } //disable comboboxes EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONGROUP), FALSE); bResult = QueryServiceConfig(schService, psci, bytesNeeded, &bytesNeeded); if (bResult) { //set key name (identical to object name) SetDlgItemText(hwndDlg, IDC_SERVICE_KEYNAME, Context->lpObjectName); //set image path info SetDlgItemText(hwndDlg, IDC_SERVICE_IMAGEPATH, psci->lpBinaryPathName); //set display name SetDlgItemText(hwndDlg, IDC_SERVICE_DISPLAYNAME, psci->lpDisplayName); //set load order group SetDlgItemText(hwndDlg, IDC_SERVICE_LOADORDERGROUP, psci->lpLoadOrderGroup); //Service Type lpType = T_UnknownType; switch (psci->dwServiceType) { case SERVICE_KERNEL_DRIVER: lpType = L"Kernel-Mode Driver"; break; case SERVICE_FILE_SYSTEM_DRIVER: lpType = L"File System Driver"; break; case SERVICE_ADAPTER: lpType = L"Adapter"; break; case SERVICE_RECOGNIZER_DRIVER: lpType = L"File System Recognizer"; break; case SERVICE_WIN32_OWN_PROCESS: lpType = L"Own Process"; break; case SERVICE_WIN32_SHARE_PROCESS: lpType = L"Share Process"; break; case (SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS): lpType = L"Own Process (Interactive)"; SetDlgItemText(hwndDlg, ID_SERVICE_NAME, psci->lpServiceStartName); break; case (SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS): lpType = L"Share Process (Interactive)"; SetDlgItemText(hwndDlg, ID_SERVICE_NAME, psci->lpServiceStartName); break; } SetDlgItemText(hwndDlg, ID_SERVICE_TYPE, lpType); //Start Type lpType = T_UnknownType; switch (psci->dwStartType) { case SERVICE_AUTO_START: lpType = L"Auto"; break; case SERVICE_BOOT_START: lpType = L"Boot"; break; case SERVICE_DEMAND_START: lpType = L"On Demand"; break; case SERVICE_DISABLED: lpType = L"Disabled"; break; case SERVICE_SYSTEM_START: lpType = L"System"; break; } SetDlgItemText(hwndDlg, ID_SERVICE_START, lpType); //Error Control lpType = T_Unknown; switch (psci->dwErrorControl) { case SERVICE_ERROR_CRITICAL: lpType = L"Critical"; break; case SERVICE_ERROR_IGNORE: lpType = L"Ignore"; break; case SERVICE_ERROR_NORMAL: lpType = L"Normal"; break; case SERVICE_ERROR_SEVERE: lpType = L"Severe"; break; } SetDlgItemText(hwndDlg, ID_SERVICE_ERROR, lpType); //dwTagId if (psci->dwTagId) { RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); ultostr(psci->dwTagId, szBuffer); SetDlgItemText(hwndDlg, ID_SERVICE_TAG, szBuffer); } else { //not assigned tag SetDlgItemText(hwndDlg, ID_SERVICE_TAG, L""); } //State RtlSecureZeroMemory(&ssp, sizeof(ssp)); if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(ssp), &bytesNeeded)) { lpType = T_Unknown; switch (ssp.dwCurrentState) { case SERVICE_STOPPED: lpType = L"Stopped"; break; case SERVICE_START_PENDING: lpType = L"Start Pending"; break; case SERVICE_STOP_PENDING: lpType = L"Stop Pending"; break; case SERVICE_RUNNING: lpType = L"Running"; break; case SERVICE_CONTINUE_PENDING: lpType = L"Continue Pending"; break; case SERVICE_PAUSE_PENDING: lpType = L"Pause Pending"; break; case SERVICE_PAUSED: lpType = L"Paused"; break; } SetDlgItemText(hwndDlg, ID_SERVICE_CURRENT, lpType); } else { SetDlgItemText(hwndDlg, ID_SERVICE_CURRENT, T_CannotQuery); } //Service Description bRet = FALSE; SetDlgItemText(hwndDlg, ID_SERVICE_DESCRIPTION, L""); bytesNeeded = 0x1000; psd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (psd) { bRet = QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)psd, bytesNeeded, &bytesNeeded); if ((bRet == FALSE) && (bytesNeeded != 0)) { HeapFree(GetProcessHeap(), 0, psd); psd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); } if (psd) { //set description or hide window bRet = QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)psd, bytesNeeded, &bytesNeeded); if (bRet) { SetDlgItemText(hwndDlg, IDC_SERVICE_DESCRIPTION, psd->lpDescription); } HeapFree(GetProcessHeap(), 0, psd); } } if (bRet == FALSE) { //not enough memory, hide description window ShowWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DESCRIPTION), SW_HIDE); } //Service Dependencies if (psci->lpDependencies) { //first list DependsOnService, DependsOnGroup nEndOfList = 0; nEnd = 0; nStart = 0; dwGroups = 0; dwServices = 0; //calc total number of symbols while ((psci->lpDependencies[nEndOfList] != L'\0') || (psci->lpDependencies[nEndOfList + 1] != L'\0')) nEndOfList++; if (nEndOfList > 0) { SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); //iterate through MULTI_SZ string do { while (psci->lpDependencies[nEnd] != L'\0') { nEnd++; } RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); //maximum bytes that can be copied is sizeof(szBuffer) _strncpy(szBuffer, sizeof(szBuffer), &psci->lpDependencies[nStart], nEnd); //check if dependency is a group (has "+" before name) fGroup = (szBuffer[0] == SC_GROUP_IDENTIFIER); if (fGroup) { SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_ADDSTRING, (WPARAM)0, (LPARAM)&szBuffer[1]); dwGroups++; } else { SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_ADDSTRING, (WPARAM)0, (LPARAM)&szBuffer); dwServices++; } nEnd++; nStart = nEnd; } while (nEnd < nEndOfList); //group present, enable combobox if (dwGroups > 0) { EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONGROUP), TRUE); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } //service present, enable combobox if (dwServices > 0) { EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE), TRUE); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } } //if (nEndOfList > 0) //second list services that depends on this service SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); dwServices = 0; bytesNeeded = 1024; bRet = FALSE; //avoid SCM unexpected behaviour by using preallocated buffer lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (lpDependencies) { bRet = EnumDependentServices(schService, SERVICE_STATE_ALL, lpDependencies, bytesNeeded, &bytesNeeded, &dwServices); if (bRet && (GetLastError() == ERROR_MORE_DATA)) { //more memory needed for enum HeapFree(GetProcessHeap(), 0, lpDependencies); dwServices = 0; lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (lpDependencies) { bRet = EnumDependentServices(schService, SERVICE_STATE_ALL, lpDependencies, bytesNeeded, &bytesNeeded, &dwServices); } } //list dependents if (bRet && dwServices) { for (i = 0; i < dwServices; i++) { ess = *(lpDependencies + i); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_ADDSTRING, (WPARAM)0, (LPARAM)ess.lpServiceName); } //enable combobox and set current selection to the first item EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES), TRUE); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } HeapFree(GetProcessHeap(), 0, lpDependencies); } } //if (psi->lpDependencies) } //bResult != FALSE CloseServiceHandle(schService); } while (cond); if (psci != NULL) { HeapFree(GetProcessHeap(), 0, psci); } if (SchSCManager) { CloseServiceHandle(SchSCManager); } if (bResult == FALSE) { EnumChildWindows(hwndDlg, DriverShowChildWindows, SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), SW_SHOW); } else { SetFocus(GetDlgItem(hwndDlg, ID_SERVICE_JUMPTOKEY)); } } __except (exceptFilter(GetExceptionCode(), GetExceptionInformation())) { EnumChildWindows(hwndDlg, DriverShowChildWindows, SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), SW_SHOW); return; } }
LRESULT CALLBACK TreeListHookProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { HWND BaseWindow = GetParent(hwnd); WNDPROC OriginalTreeProc = (WNDPROC)GetWindowLongPtr(BaseWindow, TL_TREEWNDPROC_SLOT); LPNMTTDISPINFO hdr; LPTSTR privateBuffer; TVITEMEX itemex; RECT rc, hr; PTL_SUBITEMS subitems; TOOLINFO tool; HDC dc; switch (uMsg) { case WM_NOTIFY: hdr = (LPNMTTDISPINFO)lParam; if (hdr->hdr.hwndFrom == (HWND)GetWindowLongPtr(BaseWindow, TL_TOOLTIPS_SLOT)) { switch (hdr->hdr.code) { case TTN_SHOW: RtlSecureZeroMemory(&tool, sizeof(tool)); tool.cbSize = sizeof(tool); tool.uId = hdr->hdr.idFrom; tool.hwnd = hwnd; SendMessage(hdr->hdr.hwndFrom, TTM_GETTOOLINFO, 0, (LPARAM)&tool); if (TreeView_GetItemRect(hwnd, (HTREEITEM)(hdr->hdr.idFrom - tool.lParam), &rc, TRUE)) { if (tool.lParam > 0) { Header_GetItemRect((HWND)GetWindowLongPtr(BaseWindow, TL_HEADERCONTROL_SLOT), tool.lParam, &hr); rc.left = hr.left; rc.right = hr.right; } rc.left += 3; rc.top += 1; ClientToScreen(hwnd, (LPPOINT)&rc); SendMessage(hdr->hdr.hwndFrom, TTM_ADJUSTRECT, TRUE, (LPARAM)&rc); SetWindowPos(hdr->hdr.hwndFrom, 0, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW); return TRUE; } break; case TTN_GETDISPINFO: if (!Header_GetItemRect((HWND)GetWindowLongPtr(BaseWindow, TL_HEADERCONTROL_SLOT), hdr->lParam, &hr)) break; if (!TreeView_GetItemRect(hwnd, (HTREEITEM)(hdr->hdr.idFrom - hdr->lParam), &rc, TRUE)) break; if ((hdr->lParam == 0) && (rc.right < hr.right - 1)) // is tooltip from the first column? break; privateBuffer = (LPTSTR)GetWindowLongPtr(BaseWindow, TL_TOOLTIPSBUFFER_SLOT); RtlSecureZeroMemory(&itemex, sizeof(itemex)); RtlSecureZeroMemory(privateBuffer, TL_SIZEOF_PRIVATEBUFFER); itemex.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_PARAM; itemex.cchTextMax = MAX_PATH; itemex.pszText = privateBuffer; itemex.hItem = (HTREEITEM)(hdr->hdr.idFrom - hdr->lParam); TreeView_GetItem(hwnd, &itemex); if ((hdr->lParam > 0) && (itemex.lParam != 0)) { subitems = (PTL_SUBITEMS)itemex.lParam; rc.left = hr.left + 3; rc.right = hr.right - 3; dc = GetDC(hwnd); SelectObject(dc, (HGDIOBJ)SendMessage(hwnd, WM_GETFONT, 0, 0)); DrawText(dc, subitems->Text[hdr->lParam - 1], -1, &rc, DT_VCENTER | DT_SINGLELINE | DT_CALCRECT); ReleaseDC(hwnd, dc); if (rc.right < hr.right - 2) break; _strncpy(privateBuffer, MAX_PATH, subitems->Text[hdr->lParam - 1], MAX_PATH); } hdr->lpszText = privateBuffer; break; } } break; case WM_PAINT: TreeListUpdateTooltips(BaseWindow); break; } return OriginalTreeProc(hwnd, uMsg, wParam, lParam); }
/* * supQueryDeviceDescription * * Purpose: * * Query device description from Setup API DB dump * */ BOOL supQueryDeviceDescription( _In_ LPWSTR lpDeviceName, _In_ PVOID Snapshot, _Inout_ LPWSTR Buffer, _In_ DWORD ccBuffer //size of buffer in chars ) { BOOL bResult, bIsRoot; SIZE_T Length; LPWSTR lpFullDeviceName; PSAPIDBOBJ pObj; PLIST_ENTRY Entry; PSAPIDBENTRY Item; bResult = FALSE; if ( (lpDeviceName == NULL) || (Buffer == NULL) || (ccBuffer == 0) || (Snapshot == NULL) ) { return bResult; } pObj = Snapshot; EnterCriticalSection(&pObj->objCS); lpFullDeviceName = NULL; Length = (_strlen(lpDeviceName) * sizeof(WCHAR)) + (_strlen(CurrentObjectPath) * sizeof(WCHAR)) + (2 * sizeof(WCHAR)) + sizeof(UNICODE_NULL); lpFullDeviceName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length); if (lpFullDeviceName != NULL) { // create full path device name for comparison _strcpy(lpFullDeviceName, CurrentObjectPath); bIsRoot = (_strcmpi(CurrentObjectPath, L"\\") == 0); if (bIsRoot == FALSE) { _strcat(lpFullDeviceName, L"\\"); } _strcat(lpFullDeviceName, lpDeviceName); // enumerate devices Entry = pObj->sapiDBHead.Flink; while (Entry && Entry != &pObj->sapiDBHead) { Item = CONTAINING_RECORD(Entry, SAPIDBENTRY, ListEntry); if (Item != NULL) { if (Item->lpDeviceName != NULL) { if (_strcmpi(lpFullDeviceName, Item->lpDeviceName) == 0) { if (Item->lpDeviceDesc != NULL) { _strncpy(Buffer, ccBuffer, Item->lpDeviceDesc, _strlen(Item->lpDeviceDesc)); } bResult = TRUE; break; } } } Entry = Entry->Flink; } HeapFree(GetProcessHeap(), 0, lpFullDeviceName); } LeaveCriticalSection(&pObj->objCS); return bResult; }
/* #FN# Called when the user clicks the OK button */ void /* #AS# Nothing */ CNewDiskImageDlg:: OnOK() { /* Unfortunately, edit controls do not lose the focus before handling this when the user uses accelerators */ ReceiveFocused(); if( PickFileName( FALSE, m_szDiskName, IDS_SELECT_DSK_SAVE, IDS_FILTER_ATR_XFD, "atr", PF_SAVE_FLAGS, FALSE, FILE_NONE, this ) && *m_szDiskName != '\0' ) { UINT unBytesInBootSec; UINT unBytesPerSector; UINT unSectors; UINT unImageLen; BOOL bTrans; FILE *pfImage = NULL; char szPostfix[ 5 ]; /* Receive the parameters */ unBytesInBootSec = (_GetSelCbox( IDC_NEWDISKIMAGE_BYTESINBOOT ) + 1) * 128; unBytesPerSector = (_GetSelCbox( IDC_NEWDISKIMAGE_BYTESPERSEC ) + 1) * 128; unSectors = GetDlgItemInt( IDC_NEWDISKIMAGE_SECTORS, &bTrans, FALSE ); if( !bTrans ) { Log_print( "Error while receiving content of dialog controls" ); return; } /* Image length divided by 16 */ if( unSectors <= 3 ) unImageLen = unSectors * unBytesInBootSec / 16; else unImageLen = ((unSectors - 3) * unBytesPerSector + 3 * unBytesInBootSec) / 16; /* Open the image file */ if( NULL == (pfImage = fopen( m_szDiskName, "wb" )) ) { DisplayMessage( GetSafeHwnd(), IDS_ERROR_FILE_OPEN, 0, MB_ICONEXCLAMATION | MB_OK, m_szDiskName ); return; } _strncpy( szPostfix, &m_szDiskName[ strlen( m_szDiskName ) - 4 ], 5 ); if( _stricmp( szPostfix, ".atr" ) == 0 ) { /* There is the definition of AFILE_ATR_Header structure in atari.h */ struct AFILE_ATR_Header atrHeader; ZeroMemory( &atrHeader, sizeof(AFILE_ATR_Header) ); atrHeader.magic1 = AFILE_ATR_MAGIC1; atrHeader.magic2 = AFILE_ATR_MAGIC2; atrHeader.secsizelo = unBytesPerSector & 0x00ff; atrHeader.secsizehi = (unBytesPerSector & 0xff00) >> 8; atrHeader.seccountlo = LOWORD(unImageLen) & 0x00ff; atrHeader.seccounthi = (LOWORD(unImageLen) & 0xff00) >> 8; atrHeader.hiseccountlo = HIWORD(unImageLen) & 0x00ff; atrHeader.hiseccounthi = (HIWORD(unImageLen) & 0xff00) >> 8; fwrite( &atrHeader, sizeof(AFILE_ATR_Header), 1, pfImage ); } /* Build an empty body of the image */ for( int i = 0; i < (int)unImageLen; i++ ) fwrite( "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16, 1, pfImage ); /* Close the image file */ fflush( pfImage ); fclose( pfImage ); }
/* * supQueryDriverDescription * * Purpose: * * Query driver description from SCM dump or from file version info * */ BOOL supQueryDriverDescription( _In_ LPWSTR lpDriverName, _In_ PVOID scmSnapshot, _In_ SIZE_T scmNumberOfEntries, _Inout_ LPWSTR Buffer, _In_ DWORD ccBuffer //size of buffer in chars ) { BOOL bResult, cond = FALSE; LPWSTR lpServiceName = NULL; LPWSTR lpDisplayName = NULL; LPENUM_SERVICE_STATUS_PROCESS pInfo = NULL; SIZE_T i, sz; LPTRANSLATE lpTranslate = NULL; PVOID vinfo = FALSE; DWORD dwSize, dwHandle; LRESULT lRet; HKEY hKey = NULL; WCHAR szBuffer[MAX_PATH * 2]; WCHAR szImagePath[MAX_PATH + 1]; bResult = FALSE; if ( (lpDriverName == NULL) || (Buffer == NULL) || (ccBuffer == 0) ) { return bResult; } // first attempt - look in SCM database if (scmSnapshot != NULL) { pInfo = (LPENUM_SERVICE_STATUS_PROCESS)scmSnapshot; for (i = 0; i < scmNumberOfEntries; i++){ lpServiceName = pInfo[i].lpServiceName; if (lpServiceName == NULL) { continue; } // not our driver - skip if (_strcmpi(lpServiceName, lpDriverName) != 0) { continue; } lpDisplayName = pInfo[i].lpDisplayName; if (lpDisplayName == NULL) { continue; } // driver has the same name as service - skip, there is no description available if (_strcmpi(lpDisplayName, lpDriverName) == 0) { continue; } sz = _strlen(lpDisplayName); _strncpy(Buffer, ccBuffer, lpDisplayName, sz); bResult = TRUE; break; } } // second attempt - query through registry and fs if (bResult == FALSE) { do { RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); wsprintfW(szBuffer, REGISTRYSERVICESKEY, lpDriverName); hKey = NULL; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_QUERY_VALUE, &hKey); if (ERROR_SUCCESS != lRet) { break; } RtlSecureZeroMemory(szImagePath, sizeof(szImagePath)); dwSize = sizeof(szImagePath) - sizeof(UNICODE_NULL); lRet = RegQueryValueEx(hKey, L"ImagePath", NULL, NULL, (LPBYTE)szImagePath, &dwSize); RegCloseKey(hKey); if (ERROR_SUCCESS == lRet) { dwHandle = 0; dwSize = GetFileVersionInfoSize(szImagePath, &dwHandle); if (dwSize == 0) { break; } // allocate memory for version_info structure vinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); if (vinfo == NULL) { break; } // query it from file if (!GetFileVersionInfo(szImagePath, 0, dwSize, vinfo)) { break; } // query codepage and language id info dwSize = 0; if (!VerQueryValue(vinfo, VERSION_TRANSLATION, &lpTranslate, (PUINT)&dwSize)) { break; } if (dwSize == 0) { break; } // query filedescription from file with given codepage & language id RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); wsprintf(szBuffer, VERSION_DESCRIPTION, lpTranslate[0].wLanguage, lpTranslate[0].wCodePage); // finally query pointer to version_info filedescription block data lpDisplayName = NULL; dwSize = 0; bResult = VerQueryValue(vinfo, szBuffer, &lpDisplayName, (PUINT)&dwSize); if (bResult) { _strncpy(Buffer, ccBuffer, lpDisplayName, dwSize); } HeapFree(GetProcessHeap(), 0, vinfo); } } while (cond); } return bResult; }
/* * supQuerySectionFileInfo * * Purpose: * * Query section object type File + Image description from version info block * */ BOOL supQuerySectionFileInfo( _In_opt_ HANDLE hRootDirectory, _In_ PUNICODE_STRING ObjectName, _Inout_ LPWSTR Buffer, _In_ DWORD ccBuffer //size of buffer in chars ) { HANDLE hSection; PVOID vinfo; LPWSTR pcValue, lpszFileName, lpszKnownDlls; LPTRANSLATE lpTranslate; SIZE_T cLength = 0; NTSTATUS status; DWORD dwHandle = 0, dwSize, dwInfoSize; BOOL bResult, cond = FALSE; OBJECT_ATTRIBUTES Obja; SECTION_BASIC_INFORMATION sbi; SECTION_IMAGE_INFORMATION sii; WCHAR szQueryBlock[MAX_PATH]; bResult = FALSE; if ( (ObjectName == NULL) || (Buffer == NULL) || (ccBuffer == 0) ) { return bResult; } vinfo = NULL; lpszFileName = NULL; hSection = NULL; lpszKnownDlls = NULL; do { //oleaut32.dll does not have FileDescription // open section with query access InitializeObjectAttributes(&Obja, ObjectName, OBJ_CASE_INSENSITIVE, hRootDirectory, NULL); status = NtOpenSection(&hSection, SECTION_QUERY, &Obja); if (!NT_SUCCESS(status)) break; // query section flags RtlSecureZeroMemory(&sbi, sizeof(sbi)); status = NtQuerySection(hSection, SectionBasicInformation, (PVOID)&sbi, sizeof(sbi), &cLength); if (!NT_SUCCESS(status)) break; // check if section is SEC_IMAGE | SEC_FILE if (!((sbi.AllocationAttributes & SEC_IMAGE) && (sbi.AllocationAttributes & SEC_FILE))) break; // check image machine type RtlSecureZeroMemory(&sii, sizeof(sii)); status = NtQuerySection(hSection, SectionImageInformation, (PVOID)&sii, sizeof(sii), &cLength); if (!NT_SUCCESS(status)) break; // select proper decoded KnownDlls path if (sii.Machine == IMAGE_FILE_MACHINE_I386) { lpszKnownDlls = g_lpKnownDlls32; } else if (sii.Machine == IMAGE_FILE_MACHINE_AMD64) { lpszKnownDlls = g_lpKnownDlls64; } // paranoid if (lpszKnownDlls == NULL) { RtlSecureZeroMemory(szQueryBlock, sizeof(szQueryBlock)); GetSystemDirectory(szQueryBlock, MAX_PATH); lpszKnownDlls = szQueryBlock; } // allocate memory buffer to store full filename // KnownDlls + \\ + Object->Name + \0 cLength = (_strlen(lpszKnownDlls) * sizeof(WCHAR)) + (_strlen(ObjectName->Buffer) * sizeof(WCHAR)) + 2 * sizeof(WCHAR); lpszFileName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cLength); if (lpszFileName == NULL) break; // construct target filepath _strcpy(lpszFileName, lpszKnownDlls); _strcat(lpszFileName, L"\\"); _strcat(lpszFileName, ObjectName->Buffer); // query size of version info dwSize = GetFileVersionInfoSize(lpszFileName, &dwHandle); if (dwSize == 0) break; // allocate memory for version_info structure vinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); if (vinfo == NULL) break; // query it from file if (!GetFileVersionInfo(lpszFileName, 0, dwSize, vinfo)) break; // query codepage and language id info if (!VerQueryValue(vinfo, VERSION_TRANSLATION, &lpTranslate, (PUINT)&dwInfoSize)) break; if (dwInfoSize == 0) break; // query filedescription from file with given codepage & language id RtlSecureZeroMemory(szQueryBlock, sizeof(szQueryBlock)); wsprintf(szQueryBlock, VERSION_DESCRIPTION, lpTranslate[0].wLanguage, lpTranslate[0].wCodePage); // finally query pointer to version_info filedescription block data pcValue = NULL; dwInfoSize = 0; bResult = VerQueryValue(vinfo, szQueryBlock, &pcValue, (PUINT)&dwInfoSize); if (bResult) { _strncpy(Buffer, ccBuffer, pcValue, dwInfoSize); } } while (cond); if (hSection) NtClose(hSection); if (vinfo) HeapFree(GetProcessHeap(), 0, vinfo); if (lpszFileName) HeapFree(GetProcessHeap(), 0, lpszFileName); return bResult; }
char *strncpy(char *dest, const char *src, long n) { return _strncpy(dest, src, n); }
int spawnve(int mode, const char *name, char * const argv[], char * const envp[]) { int i, j, l, n, prefix_len = 0; char *ext, *tmp, *arg1, *execname, *p_arg, *p_env, *prefix = NULL; char runtype, freeexec = 0, hswValid = 0, quoteargs = 1; ULONG appflags; const char * const *p; unsigned int runflags = 0; int retcode = -1; char errbuf[MAXNAMLEN + 1], queue[MAXNAMLEN + 1]; SWCNTRL swc; HSWITCH vioHSW; errno = ENOENT; /* EMX crashes on very long filenames... */ if (strlen (name) > MAXNAMLEN - 4) { errno = ENAMETOOLONG; return -1; } /* Find extension ordinal in exec_ext array */ ext = _getext2(name); for (i = 0; i < EXEC_EXT_COUNT; i++) { if (strcmp(ext, exec_ext[i]) == 0) goto found; } if (access(name, F_OK) == 0) errno = ENOEXEC; return -1; found: { PTIB tb; PPIB pb; /* Determine our session type */ if ((DosGetInfoBlocks(&tb, &pb) == NO_ERROR) && (vioHSW = WinQuerySwitchHandle(NULLHANDLE, pb->pib_ulpid)) && (WinQuerySwitchEntry(vioHSW, &swc) == NO_ERROR)) hswValid = 1; } switch (mode & 0xFF) { case P_WAIT: runflags |= spawn_WAIT; break; case P_PM: runflags |= spawn_SESSION | spawn_TYPE_PM; break; case P_OVERLAY: runflags |= spawn_WAIT | spawn_OVERLAY; break; case P_DETACH: runflags |= spawn_DETACH; break; } if (((runtype = exec_run[i]) == 0) && (DosQueryAppType((PSZ)name, &appflags) == NO_ERROR) && ((runflags & spawn_DETACH) == 0) && (hswValid)) { /* Compare to application type */ switch (appflags & 7) { case FAPPTYP_NOTSPEC: /* Methinks its a DOS proggy */ { if (appflags & FAPPTYP_DOS) if (swc.bProgType == PROG_FULLSCREEN) runflags |= (spawn_SESSION | spawn_TYPE_VDM); else runflags |= (spawn_SESSION | spawn_TYPE_WINDOWEDVDM); else runflags |= (spawn_SESSION | spawn_TYPE_DEFAULT); break; } case FAPPTYP_NOTWINDOWCOMPAT: { if (swc.bProgType != PROG_FULLSCREEN) runflags |= (spawn_SESSION | spawn_TYPE_FULLSCREEN); break; } case FAPPTYP_WINDOWCOMPAT: { /* That'll do it */ break; } case FAPPTYP_WINDOWAPI: { runflags |= (spawn_SESSION | spawn_TYPE_PM); break; } default: { runtype = 1; /* Let $COMSPEC decide what to do */ break; } } } fallback: switch (runtype) { case 0: directrun: if ((runflags & spawn_SESSION) && (((runflags & spawn_TYPE) == spawn_TYPE_VDM) || ((runflags & spawn_TYPE) == spawn_TYPE_WINDOWEDVDM))) { /* DOS command interpreter does not understand '/'s */ execname = savestring((char *)name); freeexec = 1; for (tmp = execname; *tmp; tmp++) if (*tmp == '/') *tmp = '\\'; } else execname = (char *)name; break; case 1: execname = get_string_value ("COMSPEC"); if (!execname) { internal_error("COMSPEC variable not defined"); errno = EACCES; return -1; } prefix_len = strlen(execname) + 1; prefix = alloca(prefix_len + 2 + 1 + strlen(name) + 1); strcpy(prefix, execname); emx_deunixify(prefix); strcpy((char *)&prefix[prefix_len - 1], " /c "); prefix_len += 2 + 1; strcpy((char *)&prefix[prefix_len], name); prefix_len += strlen(name) + 1; break; case 2: default: { /* We must define HAVE_HASH_BANG_EXEC since we`re processing #! here */ FILE *f; char line[MAXNAMLEN + 3]; line[0] = 0; if (!(f = fopen(name, "rt"))) { errno = ENOENT; return -1; }; fgets((char *)&line, sizeof(line), f); fclose(f); if (line[0] != '#') /* Try to run as regular executable */ goto directrun; if (line[1] != '!') { /* Run script using current shell */ strcpy((char *)&line, "#! "); strcat((char *)&line, shell_name); } n = strlen(line); while ((n > 0) && ((line[n - 1] < ' ') || (whitespace(line[n])))) n--; for (i = 2; whitespace(line[i]) && i < n; i++) ; for (j = i; (!whitespace(line[j])) && j < n; j++) ; l = i; j++; tmp = xmalloc(j - i); _strncpy(tmp, (char *)&line[i], j - i); execname = find_user_command(tmp); free(tmp); freeexec = 1; prefix_len = n - l + 1 + 1 + strlen(name); prefix = alloca(prefix_len + 1); _strncpy(prefix, (char *)&line[l], n - l + 1); strcat(prefix, " "); strcat(prefix, name); break; } } if ((execname == NULL) || (access(execname, F_OK) != 0)) { if (execname == NULL) { errno = ENOEXEC; return -1; } execname = savestring(execname); freeexec = 1; if ((ext_file_status(&execname) & FS_EXISTS) == 0) { free(execname); errno = ENOENT; return -1; } } { char *qlist = get_string_value ("BASH_NOQUOTEARGS"); char *tmp, *name = _getname (execname); int namelen; tmp = _getext (name); namelen = (tmp ? (int) (tmp - name) : strlen (name)); while (qlist) { tmp = strchr (qlist, ';'); if (!(j = tmp ? (int) (tmp - qlist) : strlen (qlist))) break; if ((namelen == j) && (memicmp (qlist, name, namelen) == 0)) { quoteargs = 0; break; } qlist += j; while (qlist[0] == ';') qlist++; } } /* Prepare command-line string */ j = prefix_len + 2; for (i = 0; i <= 1; i++) { for (p = (const char **)argv; *p != NULL; ++p) { if (p != (const char **)argv) if (i == 0) // Add a space before args starting from 1 j++; else strcat(p_arg, " "); else if (prefix_len) continue; // Prefix already contains argv[0] // If argv[i] contains a space or tab, we should put it in quotes if (strchr(*p, ' ') || strchr(*p, '\t')) if (i == 0) j += 1 + (quoteargs ? q_strlen(*p) : strlen(*p)) + 1; else { strcat(p_arg, "\""); if (quoteargs) q_strcat (p_arg, *p); else strcat (p_arg, *p); strcat(p_arg, "\""); } else // If we`re running a EMX program, we should backquote all '"'s in argv[i] if (i == 0) j += (quoteargs ? q_strlen(*p) : strlen(*p)); else if (quoteargs) q_strcat(p_arg, *p); else strcat(p_arg, *p); } if (i == 0) { p_arg = alloca(j); if (prefix_len) { memcpy(p_arg, prefix, prefix_len); p_arg[prefix_len] = ' '; p_arg[prefix_len + 1] = 0; } else *p_arg = 0; } } p_arg[strlen(p_arg) + 1] = 0; #if 0 printf("quoteargs = %d\n", quoteargs); printf("exec{%s}\n", execname); printf("args{%s}\n", p_arg); #endif for (arg1 = p_arg; !whitespace(*arg1) && *arg1; arg1++) ; *arg1++ = 0; /* Prepare environment */ j = 1; for (p = (const char * const *)envp; *p != NULL; ++p) j += strlen (*p) + 1; p_env = tmp = alloca(j); for (p = (const char * const *)envp; *p != NULL; ++p) { i = strlen (*p); memcpy(tmp, *p, i+1); tmp += i+1; } *tmp = 0; if (runflags & spawn_SESSION) /* Use DosStartSession */ { HQUEUE hq; /* Termination queue management */ sprintf((char *)&queue, "\\QUEUES\\bash%d", getpid()); if (DosCreateQueue(&hq, QUE_FIFO | QUE_CONVERT_ADDRESS, (PSZ)queue) == NO_ERROR) { STARTDATA sd; ULONG sid,pid; APIRET r; memset(&sd, 0, sizeof(sd)); sd.Length = sizeof(sd); sd.Related = (runflags & spawn_WAIT ? SSF_RELATED_CHILD : SSF_RELATED_INDEPENDENT); sd.FgBg = SSF_FGBG_FORE; sd.PgmName = execname; sd.PgmInputs = arg1; sd.TermQ = (PBYTE)&queue; sd.Environment = p_env; sd.InheritOpt = SSF_INHERTOPT_PARENT; sd.SessionType = (runflags & spawn_TYPE) >> 16; sd.ObjectBuffer = (PSZ)&errbuf; sd.ObjectBuffLen = sizeof(errbuf); #if 0 sd.PgmControl = SSF_CONTROL_NOAUTOCLOSE; #endif r = DosStartSession(&sd, &sid, &pid); if (r == NO_ERROR || r == ERROR_SMG_START_IN_BACKGROUND) { if (runflags & spawn_WAIT) { REQUESTDATA rd; ULONG Length; PUSHORT Info = NULL; BYTE Priority; ULONG oldVis, oldJump; SWP oldpos; if (hswValid) { /* Exclude session from task list */ oldVis = swc.uchVisibility; swc.uchVisibility = SWL_INVISIBLE; oldJump = swc.fbJump; swc.fbJump = SWL_NOTJUMPABLE; WinChangeSwitchEntry(vioHSW, &swc); /* Minimize session */ WinQueryWindowPos(swc.hwnd, &oldpos); if ((oldpos.fl & SWP_MINIMIZE) == 0) WinPostMsg(swc.hwnd, WM_SYSCOMMAND, (MPARAM)SC_MINIMIZE, MPFROM2SHORT(CMDSRC_MENU, FALSE)); } DosReadQueue(hq, &rd, &Length, (PPVOID)&Info, 0, DCWW_WAIT, &Priority, 0); if (hswValid) { /* Restore jumpable & visible status */ swc.uchVisibility = oldVis; swc.fbJump = oldJump; WinChangeSwitchEntry(vioHSW, &swc); /* Restore session */ if ((oldpos.fl & SWP_MINIMIZE) == 0) { WinPostMsg(swc.hwnd, WM_SYSCOMMAND, (MPARAM)SC_RESTORE, MPFROM2SHORT(CMDSRC_MENU, FALSE)); WinSetWindowPos(swc.hwnd, oldpos.hwndInsertBehind, oldpos.x, oldpos.y, oldpos.cx, oldpos.cy, oldpos.fl); } } retcode = Info[1]; } else retcode = pid; } else internal_error("Execution failed because of module \"%s\"", (char *)&errbuf); DosCloseQueue(hq); } else