QString QBasicFontDatabase::fontNameFromTTFile(const QString &filename) { QFile f(filename); QString retVal; qint64 bytesRead; qint64 bytesToRead; if (f.open(QIODevice::ReadOnly)) { OFFSET_TABLE ttOffsetTable; bytesToRead = sizeof(OFFSET_TABLE); bytesRead = f.read((char*)&ttOffsetTable, bytesToRead); if (bytesToRead != bytesRead) return retVal; ttOffsetTable.numTables = qFromBigEndian(ttOffsetTable.numTables); ttOffsetTable.majorVersion = qFromBigEndian(ttOffsetTable.majorVersion); ttOffsetTable.minorVersion = qFromBigEndian(ttOffsetTable.minorVersion); if (ttOffsetTable.majorVersion != 1 || ttOffsetTable.minorVersion != 0) return retVal; TABLE_DIRECTORY tblDir; bool found = false; for (int i = 0; i < ttOffsetTable.numTables; i++) { bytesToRead = sizeof(TABLE_DIRECTORY); bytesRead = f.read((char*)&tblDir, bytesToRead); if (bytesToRead != bytesRead) return retVal; if (qFromBigEndian(tblDir.tag) == MAKE_TAG('n', 'a', 'm', 'e')) { found = true; tblDir.length = qFromBigEndian(tblDir.length); tblDir.offset = qFromBigEndian(tblDir.offset); break; } } if (found) { f.seek(tblDir.offset); NAME_TABLE_HEADER ttNTHeader; bytesToRead = sizeof(NAME_TABLE_HEADER); bytesRead = f.read((char*)&ttNTHeader, bytesToRead); if (bytesToRead != bytesRead) return retVal; ttNTHeader.nrCount = qFromBigEndian(ttNTHeader.nrCount); ttNTHeader.storageOffset = qFromBigEndian(ttNTHeader.storageOffset); NAME_RECORD ttRecord; found = false; for (int i = 0; i < ttNTHeader.nrCount; i++) { bytesToRead = sizeof(NAME_RECORD); bytesRead = f.read((char*)&ttRecord, bytesToRead); if (bytesToRead != bytesRead) return retVal; ttRecord.nameID = qFromBigEndian(ttRecord.nameID); if (ttRecord.nameID == 1) { ttRecord.stringLength = qFromBigEndian(ttRecord.stringLength); ttRecord.stringOffset = qFromBigEndian(ttRecord.stringOffset); int nPos = f.pos(); f.seek(tblDir.offset + ttRecord.stringOffset + ttNTHeader.storageOffset); QByteArray nameByteArray = f.read(ttRecord.stringLength); if (!nameByteArray.isEmpty()) { if (ttRecord.encodingID == 256 || ttRecord.encodingID == 768) { //This is UTF-16 in big endian int stringLength = ttRecord.stringLength / 2; retVal.resize(stringLength); QChar *data = retVal.data(); const ushort *srcData = (const ushort *)nameByteArray.data(); for (int i = 0; i < stringLength; ++i) data[i] = qFromBigEndian(srcData[i]); return retVal; } else if (ttRecord.encodingID == 0) { //This is Latin1 retVal = QString::fromLatin1(nameByteArray); } else { qWarning("Could not retrieve Font name from file: %s", qPrintable(QDir::toNativeSeparators(filename))); } break; } f.seek(nPos); } } } f.close(); } return retVal; }
bool QFontEngineWin::hasCMapTable() const { HDC hdc = shared_dc(); SelectObject(hdc, hfont); return GetFontData(hdc, MAKE_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR; }
int krb5_kdc_save_request(krb5_context context, const char *fn, const unsigned char *buf, size_t len, const krb5_data *reply, const struct sockaddr *sa) { krb5_storage *sp; krb5_address a; int fd, ret; uint32_t t; krb5_data d; memset(&a, 0, sizeof(a)); d.data = rk_UNCONST(buf); d.length = len; t = _kdc_now.tv_sec; fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600); if (fd < 0) { int saved_errno = errno; krb5_set_error_message(context, saved_errno, "Failed to open: %s", fn); return saved_errno; } sp = krb5_storage_from_fd(fd); close(fd); if (sp == NULL) { krb5_set_error_message(context, ENOMEM, "Storage failed to open fd"); return ENOMEM; } ret = krb5_sockaddr2address(context, sa, &a); if (ret) goto out; krb5_store_uint32(sp, 1); krb5_store_uint32(sp, t); krb5_store_address(sp, a); krb5_store_data(sp, d); { Der_class cl; Der_type ty; unsigned int tag; ret = der_get_tag (reply->data, reply->length, &cl, &ty, &tag, NULL); if (ret) { krb5_store_uint32(sp, 0xffffffff); krb5_store_uint32(sp, 0xffffffff); } else { krb5_store_uint32(sp, MAKE_TAG(cl, ty, 0)); krb5_store_uint32(sp, tag); } } krb5_free_address(context, &a); out: krb5_storage_free(sp); return 0; }
NTSTATUS InheritIoHandleTable( IN PCONSOLE_PER_PROCESS_DATA ProcessData, IN PCSR_PROCESS ParentProcess ) /*++ Routine Description: This routine creates a process's handle table from the parent process's handle table. ProcessData contains the process data copied directly from the parent to the child process by CSR. This routine allocates a new handle table, if necessary, then invalidates non-inherited handles and increments the sharing and reference counts for inherited handles. Arguments: ProcessData - Pointer to per process data structure. Return Value: Note: The console lock must be held when calling this routine. --*/ { //PHANDLE_DATA ParentTable; ULONG i; NTSTATUS Status; PCONSOLE_INFORMATION Console; PCONSOLE_PER_PROCESS_DATA ParentProcessData; // // If there is a parent process, copy its handles. // if (ParentProcess != NULL) { // // Copy handles from parent process. If the table size // is CONSOLE_INITIAL_IO_HANDLES, CSR has done the copy // for us. // ParentProcessData = CONSOLE_FROMPROCESSPERPROCESSDATA(ParentProcess); ASSERT(ParentProcessData->Foo == 0xF00); ASSERT(ParentProcessData->HandleTableSize != 0); ASSERT(ParentProcessData->HandleTableSize <= 0x0000FFFF); if (ParentProcessData->HandleTableSize != CONSOLE_INITIAL_IO_HANDLES) { ProcessData->HandleTableSize = ParentProcessData->HandleTableSize; ProcessData->HandleTablePtr = (PHANDLE_DATA)HeapAlloc(pConHeap,MAKE_TAG( HANDLE_TAG ),ProcessData->HandleTableSize * sizeof(HANDLE_DATA)); if (ProcessData->HandleTablePtr == NULL) { ProcessData->HandleTablePtr = ProcessData->HandleTable; ProcessData->HandleTableSize = CONSOLE_INITIAL_IO_HANDLES; return STATUS_NO_MEMORY; } RtlCopyMemory(ProcessData->HandleTablePtr, ParentProcessData->HandleTablePtr, ProcessData->HandleTableSize * sizeof(HANDLE_DATA)); } } else { // // This process no longer has a parent, so mark all handles // as free and fail. // for (i=0; i<ProcessData->HandleTableSize; i++) { ProcessData->HandleTablePtr[i].HandleType = CONSOLE_FREE_HANDLE; } return STATUS_PROCESS_IS_TERMINATING; } Status = DereferenceConsoleHandle(CONSOLE_GETCONSOLEHANDLE(),&Console); ASSERT (NT_SUCCESS(Status)); if (Console->Flags & CONSOLE_SHUTTING_DOWN) { for (i=0; i<ProcessData->HandleTableSize; i++) { ProcessData->HandleTablePtr[i].HandleType = CONSOLE_FREE_HANDLE; } return STATUS_PROCESS_IS_TERMINATING; } for (i=0; i<ProcessData->HandleTableSize; i++) { if (ProcessData->HandleTablePtr[i].HandleType & CONSOLE_INHERITABLE) { PSHARE_ACCESS ShareAccess; // // increment buffer info reference count. we're effectively // doing a dup here. // if (ProcessData->HandleTablePtr[i].HandleType & CONSOLE_INPUT_HANDLE) { ProcessData->HandleTablePtr[i].InputReadData = (PINPUT_READ_HANDLE_DATA)HeapAlloc(pConHeap,MAKE_TAG( HANDLE_TAG ),sizeof(INPUT_READ_HANDLE_DATA)); if (!ProcessData->HandleTablePtr[i].InputReadData) { if (ProcessData->HandleTableSize != CONSOLE_INITIAL_IO_HANDLES) { HeapFree(pConHeap,0,ProcessData->HandleTablePtr); } ProcessData->HandleTablePtr = (PVOID)0x70707070; return STATUS_NO_MEMORY; } ProcessData->HandleTablePtr[i].InputReadData->InputHandleFlags = 0; ProcessData->HandleTablePtr[i].InputReadData->ReadCount = 0; RtlInitializeCriticalSection(&ProcessData->HandleTablePtr[i].InputReadData->ReadCountLock); ProcessData->HandleTablePtr[i].Buffer.InputBuffer->RefCount++; ShareAccess = &ProcessData->HandleTablePtr[i].Buffer.InputBuffer->ShareAccess; } else { ProcessData->HandleTablePtr[i].Buffer.ScreenBuffer->RefCount++; ShareAccess = &ProcessData->HandleTablePtr[i].Buffer.ScreenBuffer->ShareAccess; } // // dup sharing // Status = ConsoleDupShare(ProcessData->HandleTablePtr[i].Access, ProcessData->HandleTablePtr[i].ShareAccess, ShareAccess, &ProcessData->HandleTablePtr[i] ); ASSERT (NT_SUCCESS(Status)); } else { ProcessData->HandleTablePtr[i].HandleType = CONSOLE_FREE_HANDLE; } } ASSERT(ProcessData->Foo == 0xF00); return STATUS_SUCCESS; }
VOID DoStringPaste( IN PCONSOLE_INFORMATION Console, IN PWCHAR pwStr, IN UINT DataSize ) { PINPUT_RECORD StringData,CurRecord; PWCHAR CurChar; WCHAR Char; DWORD i; DWORD ChunkSize,j; ULONG EventsWritten; if(!pwStr) { return; } if (DataSize > DATA_CHUNK_SIZE) { ChunkSize = DATA_CHUNK_SIZE; } else { ChunkSize = DataSize; } // // allocate space to copy data. // StringData = (PINPUT_RECORD)HeapAlloc(pConHeap,MAKE_TAG( TMP_TAG ),(ChunkSize/sizeof(WCHAR))*sizeof(INPUT_RECORD)*8); // 8 is maximum number of events per char if (StringData == NULL) { return; } // // transfer data to the input buffer in chunks // CurChar = pwStr; // LATER remove this for (j = 0; j < DataSize; j += ChunkSize) { if (ChunkSize > DataSize - j) { ChunkSize = DataSize - j; } CurRecord = StringData; for (i = 0, EventsWritten = 0; i < ChunkSize; i++) { // filter out LF if not first char and preceded by CR Char = *CurChar; if (Char != UNICODE_LINEFEED || (i==0 && j==0) || (*(CurChar-1)) != UNICODE_CARRIAGERETURN) { SHORT KeyState; BYTE KeyFlags; BOOL AltGr=FALSE; BOOL Shift=FALSE; if (Char == 0) { j = DataSize; break; } KeyState = VkKeyScan(Char); // if VkKeyScanW fails (char is not in kbd layout), we must // emulate the key being input through the numpad if (KeyState == -1) { CHAR CharString[4]; UCHAR OemChar; PCHAR pCharString; ConvertToOem(Console->OutputCP, &Char, 1, &OemChar, 1 ); _itoa(OemChar, CharString, 10); EventsWritten++; LoadKeyEvent(CurRecord,TRUE,0,VK_MENU,0x38,LEFT_ALT_PRESSED); CurRecord++; for (pCharString=CharString;*pCharString;pCharString++) { WORD wVirtualKey, wScancode; EventsWritten++; wVirtualKey = *pCharString-'0'+VK_NUMPAD0; wScancode = MapVirtualKey(wVirtualKey, 0); LoadKeyEvent(CurRecord,TRUE,0,wVirtualKey,wScancode,LEFT_ALT_PRESSED); CurRecord++; EventsWritten++; LoadKeyEvent(CurRecord,FALSE,0,wVirtualKey,wScancode,LEFT_ALT_PRESSED); CurRecord++; } EventsWritten++; LoadKeyEvent(CurRecord,FALSE,Char,VK_MENU,0x38,0); CurRecord++; } else { KeyFlags = HIBYTE(KeyState); // handle yucky alt-gr keys if ((KeyFlags & 6) == 6) { AltGr=TRUE; EventsWritten++; LoadKeyEvent(CurRecord,TRUE,0,VK_MENU,0x38,ENHANCED_KEY | LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED); CurRecord++; } else if (KeyFlags & 1) { Shift=TRUE; EventsWritten++; LoadKeyEvent(CurRecord,TRUE,0,VK_SHIFT,0x2a,SHIFT_PRESSED); CurRecord++; } EventsWritten++; LoadKeyEvent(CurRecord, TRUE, Char, LOBYTE(KeyState), MapVirtualKey(CurRecord->Event.KeyEvent.wVirtualKeyCode,0), 0); if (KeyFlags & 1) CurRecord->Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED; if (KeyFlags & 2) CurRecord->Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED; if (KeyFlags & 4) CurRecord->Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED; CurRecord++; EventsWritten++; *CurRecord = *(CurRecord-1); CurRecord->Event.KeyEvent.bKeyDown = FALSE; CurRecord++; // handle yucky alt-gr keys if (AltGr) { EventsWritten++; LoadKeyEvent(CurRecord,FALSE,0,VK_MENU,0x38,ENHANCED_KEY); CurRecord++; } else if (Shift) { EventsWritten++; LoadKeyEvent(CurRecord,FALSE,0,VK_SHIFT,0x2a,0); CurRecord++; } } } CurChar++; } EventsWritten = WriteInputBuffer(Console, &Console->InputBuffer, StringData, EventsWritten ); } HeapFree(pConHeap,0,StringData); return; }
int main(int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_kdc_configuration *config; krb5_storage *sp; int fd, optidx = 0; setprogname(argv[0]); if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if(help_flag) usage(0); if(version_flag){ print_version(NULL); exit(0); } ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed to parse configuration file"); ret = krb5_kdc_get_config(context, &config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_default_config"); kdc_openlog(context, "kdc-replay", config); ret = krb5_kdc_set_dbinfo(context, config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo"); #ifdef PKINIT if (config->enable_pkinit) { if (config->pkinit_kdc_identity == NULL) krb5_errx(context, 1, "pkinit enabled but no identity"); if (config->pkinit_kdc_anchors == NULL) krb5_errx(context, 1, "pkinit enabled but no X509 anchors"); krb5_kdc_pk_initialize(context, config, config->pkinit_kdc_identity, config->pkinit_kdc_anchors, config->pkinit_kdc_cert_pool, config->pkinit_kdc_revoke); } #endif /* PKINIT */ if (argc != 2) errx(1, "argc != 2"); printf("kdc replay\n"); fd = open(argv[1], O_RDONLY); if (fd < 0) err(1, "open: %s", argv[1]); sp = krb5_storage_from_fd(fd); if (sp == NULL) krb5_errx(context, 1, "krb5_storage_from_fd"); while(1) { struct sockaddr_storage sa; krb5_socklen_t salen = sizeof(sa); struct timeval tv; krb5_address a; krb5_data d, r; uint32_t t, clty, tag; char astr[80]; ret = krb5_ret_uint32(sp, &t); if (ret == HEIM_ERR_EOF) break; else if (ret) krb5_errx(context, 1, "krb5_ret_uint32(version)"); if (t != 1) krb5_errx(context, 1, "version not 1"); ret = krb5_ret_uint32(sp, &t); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(time)"); ret = krb5_ret_address(sp, &a); if (ret) krb5_errx(context, 1, "krb5_ret_address"); ret = krb5_ret_data(sp, &d); if (ret) krb5_errx(context, 1, "krb5_ret_data"); ret = krb5_ret_uint32(sp, &clty); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(class|type)"); ret = krb5_ret_uint32(sp, &tag); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(tag)"); ret = krb5_addr2sockaddr (context, &a, (struct sockaddr *)&sa, &salen, 88); if (ret == KRB5_PROG_ATYPE_NOSUPP) goto out; else if (ret) krb5_err(context, 1, ret, "krb5_addr2sockaddr"); ret = krb5_print_address(&a, astr, sizeof(astr), NULL); if (ret) krb5_err(context, 1, ret, "krb5_print_address"); printf("processing request from %s, %lu bytes\n", astr, (unsigned long)d.length); r.length = 0; r.data = NULL; tv.tv_sec = t; tv.tv_usec = 0; krb5_kdc_update_time(&tv); krb5_set_real_time(context, tv.tv_sec, 0); ret = krb5_kdc_process_request(context, config, d.data, d.length, &r, NULL, astr, (struct sockaddr *)&sa, 0); if (ret) krb5_err(context, 1, ret, "krb5_kdc_process_request"); if (r.length) { Der_class cl; Der_type ty; unsigned int tag2; ret = der_get_tag (r.data, r.length, &cl, &ty, &tag2, NULL); if (MAKE_TAG(cl, ty, 0) != clty) krb5_errx(context, 1, "class|type mismatch: %d != %d", (int)MAKE_TAG(cl, ty, 0), (int)clty); if (tag != tag2) krb5_errx(context, 1, "tag mismatch"); krb5_data_free(&r); } else { if (clty != 0xffffffff) krb5_errx(context, 1, "clty not invalid"); if (tag != 0xffffffff) krb5_errx(context, 1, "tag not invalid"); } out: krb5_data_free(&d); krb5_free_address(context, &a); } krb5_storage_free(sp); krb5_free_context(context); printf("done\n"); return 0; }
krb5_error_code hdb_replace_extension(krb5_context context, hdb_entry *entry, const HDB_extension *ext) { HDB_extension *ext2; HDB_extension *es; int ret; ext2 = NULL; if (entry->extensions == NULL) { entry->extensions = calloc(1, sizeof(*entry->extensions)); if (entry->extensions == NULL) { krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } else if (ext->data.element != choice_HDB_extension_data_asn1_ellipsis) { ext2 = hdb_find_extension(entry, ext->data.element); } else { /* * This is an unknown extention, and we are asked to replace a * possible entry in `entry' that is of the same type. This * might seem impossible, but ASN.1 CHOICE comes to our * rescue. The first tag in each branch in the CHOICE is * unique, so just find the element in the list that have the * same tag was we are putting into the list. */ Der_class replace_class, list_class; Der_type replace_type, list_type; unsigned int replace_tag, list_tag; size_t size; size_t i; ret = der_get_tag(ext->data.u.asn1_ellipsis.data, ext->data.u.asn1_ellipsis.length, &replace_class, &replace_type, &replace_tag, &size); if (ret) { krb5_set_error_message(context, ret, "hdb: failed to decode " "replacement hdb extention"); return ret; } for (i = 0; i < entry->extensions->len; i++) { HDB_extension *ext3 = &entry->extensions->val[i]; if (ext3->data.element != choice_HDB_extension_data_asn1_ellipsis) continue; ret = der_get_tag(ext3->data.u.asn1_ellipsis.data, ext3->data.u.asn1_ellipsis.length, &list_class, &list_type, &list_tag, &size); if (ret) { krb5_set_error_message(context, ret, "hdb: failed to decode " "present hdb extention"); return ret; } if (MAKE_TAG(replace_class,replace_type,replace_type) == MAKE_TAG(list_class,list_type,list_type)) { ext2 = ext3; break; } } } if (ext2) { free_HDB_extension(ext2); ret = copy_HDB_extension(ext, ext2); if (ret) krb5_set_error_message(context, ret, "hdb: failed to copy replacement " "hdb extention"); return ret; } es = realloc(entry->extensions->val, (entry->extensions->len+1)*sizeof(entry->extensions->val[0])); if (es == NULL) { krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } entry->extensions->val = es; ret = copy_HDB_extension(ext, &entry->extensions->val[entry->extensions->len]); if (ret == 0) entry->extensions->len++; else krb5_set_error_message(context, ret, "hdb: failed to copy new extension"); return ret; }
NTSTATUS RealUnicodeToFalseUnicode( IN OUT LPWSTR Source, IN int SourceLength, // in chars IN UINT Codepage ) /* this routine converts a unicode string into the correct characters for an OEM (cp 437) font. this code is needed because the gdi glyph mapper converts unicode to ansi using codepage 1252 to index font. this is how the data is stored internally. */ { NTSTATUS Status; LPSTR Temp; ULONG TempLength; ULONG Length; CHAR StackBuffer[STACK_BUFFER_SIZE]; BOOL NormalChars; int i; DBGCHARS(("RealUnicodeToFalseUnicode U->%d:ACP->U %.*ls\n", Codepage, SourceLength > 10 ? 10 : SourceLength, Source)); NormalChars = TRUE; for (i=0;i<SourceLength;i++) { if (Source[i] > 0x7f) { NormalChars = FALSE; break; } } if (NormalChars) { return STATUS_SUCCESS; } TempLength = SourceLength; if (TempLength > STACK_BUFFER_SIZE) { Temp = (LPSTR)HeapAlloc(pConHeap,MAKE_TAG( TMP_TAG ),TempLength); if (Temp == NULL) { return STATUS_NO_MEMORY; } } else { Temp = StackBuffer; } if (Codepage == OEMCP) { Status = RtlUnicodeToOemN(Temp, TempLength, &Length, Source, SourceLength * sizeof(WCHAR) ); } else { Status = WideCharToMultiByte(Codepage, 0, Source, SourceLength, Temp, TempLength, NULL, NULL); } if (!NT_SUCCESS(Status)) { if (TempLength > STACK_BUFFER_SIZE) { HeapFree(pConHeap,0,Temp); } return Status; } Status = RtlMultiByteToUnicodeN(Source, SourceLength * sizeof(WCHAR), &Length, Temp, TempLength ); if (TempLength > STACK_BUFFER_SIZE) { HeapFree(pConHeap,0,Temp); } if (!NT_SUCCESS(Status)) { return Status; } else { return STATUS_SUCCESS; } }
NTSTATUS FalseUnicodeToRealUnicode( IN OUT LPWSTR Source, IN int SourceLength, // in chars IN UINT Codepage ) /* this routine converts a unicode string from the internally stored unicode characters into the real unicode characters. */ { NTSTATUS Status; LPSTR Temp; ULONG TempLength; ULONG Length; CHAR StackBuffer[STACK_BUFFER_SIZE]; BOOL NormalChars; int i; DBGCHARS(("UnicodeAnsiToUnicodeAnsi U->ACP:%d->U %.*ls\n", Codepage, SourceLength > 10 ? 10 : SourceLength, Source)); NormalChars = TRUE; /* * Test for characters < 0x20 or >= 0x7F. If none are found, we don't have * any conversion to do! */ for (i=0;i<SourceLength;i++) { if ((USHORT)(Source[i] - 0x20) > 0x5e) { NormalChars = FALSE; break; } } if (NormalChars) { return STATUS_SUCCESS; } TempLength = SourceLength; if (TempLength > STACK_BUFFER_SIZE) { Temp = (LPSTR)HeapAlloc(pConHeap,MAKE_TAG( TMP_TAG ),TempLength); if (Temp == NULL) { return STATUS_NO_MEMORY; } } else { Temp = StackBuffer; } Status = RtlUnicodeToMultiByteN(Temp, TempLength, &Length, Source, SourceLength * sizeof(WCHAR) ); if (!NT_SUCCESS(Status)) { if (TempLength > STACK_BUFFER_SIZE) { HeapFree(pConHeap,0,Temp); } return Status; } if (Codepage == OEMCP) { Status = RtlCustomCPToUnicodeN(&GlyphCP, Source, SourceLength * sizeof(WCHAR), &Length, Temp, TempLength ); } else { Status = MultiByteToWideChar(Codepage, MB_USEGLYPHCHARS, Temp, TempLength*sizeof(WCHAR), Source, SourceLength); } if (TempLength > STACK_BUFFER_SIZE) { HeapFree(pConHeap,0,Temp); } if (!NT_SUCCESS(Status)) { return Status; } else { return STATUS_SUCCESS; } }
ULONG BaseSrvDebugProcess( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) { NTSTATUS Status; PBASE_DEBUGPROCESS_MSG a = (PBASE_DEBUGPROCESS_MSG)&m->u.ApiMessageData; HANDLE Thread,ProcessHandle,Token; PCSR_PROCESS Process; DWORD ThreadId; PTOKEN_DEFAULT_DACL lpDefaultDacl; TOKEN_DEFAULT_DACL DefaultDacl; ULONG DaclLength; SECURITY_ATTRIBUTES ThreadAttributes; SECURITY_DESCRIPTOR SecurityDescriptor; UNICODE_STRING ModuleNameString_U; PVOID ModuleHandle; STRING ProcedureNameString; PCREATE_REMOTE_THREAD CreateRemoteThreadRoutine; if (a->dwProcessId == -1 && a->AttachCompleteRoutine == NULL) { HANDLE DebugPort; DebugPort = (HANDLE)NULL; Status = NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, (PVOID)&DebugPort, sizeof(DebugPort), NULL ); if ( NT_SUCCESS(Status) && DebugPort ) { return (ULONG)STATUS_ACCESS_DENIED; } return STATUS_SUCCESS; } #if DEVL if (a->dwProcessId != -1) { #endif // DEVL if ( a->AttachCompleteRoutine == NULL ) { Status = CsrLockProcessByClientId((HANDLE)a->dwProcessId,&Process); if ( NT_SUCCESS(Status) ) { ProcessHandle = Process->ProcessHandle; Status = NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &Token ); if ( !NT_SUCCESS(Status) ) { CsrUnlockProcess(Process); return Status; } lpDefaultDacl = &DefaultDacl; Status = NtQueryInformationToken(Token, TokenDefaultDacl, lpDefaultDacl, sizeof(DefaultDacl), &DaclLength ); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) { Status = STATUS_ACCESS_DENIED; } else { Status = STATUS_SUCCESS; } if ( Process->DebugUserInterface.UniqueProcess || Process->DebugUserInterface.UniqueThread ) { Status = STATUS_ACCESS_DENIED; } NtClose(Token); CsrUnlockProcess(Process); } return (ULONG)Status; } // // Can't call base, but I know it is there // RtlInitUnicodeString( &ModuleNameString_U, L"kernel32" ); Status = LdrLoadDll( UNICODE_NULL, NULL, &ModuleNameString_U, &ModuleHandle ); if ( !NT_SUCCESS(Status) ) { return (ULONG)Status; } RtlInitString( &ProcedureNameString, "CreateRemoteThread" ); Status = LdrGetProcedureAddress( ModuleHandle, &ProcedureNameString, (ULONG) NULL, (PVOID *) &CreateRemoteThreadRoutine ); if ( !NT_SUCCESS(Status) ) { LdrUnloadDll( ModuleHandle ); return (ULONG)Status; } Status = CsrLockProcessByClientId((HANDLE)a->dwProcessId,&Process); if ( NT_SUCCESS(Status) ) { ProcessHandle = Process->ProcessHandle; Status = NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &Token ); if (!NT_SUCCESS(Status)) { CsrUnlockProcess(Process); LdrUnloadDll( ModuleHandle ); return (ULONG)Status; } lpDefaultDacl = &DefaultDacl; Status = NtQueryInformationToken(Token, TokenDefaultDacl, lpDefaultDacl, sizeof(DefaultDacl), &DaclLength ); if (!NT_SUCCESS(Status)) { lpDefaultDacl = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ), DaclLength); if (lpDefaultDacl) { Status = NtQueryInformationToken(Token, TokenDefaultDacl, lpDefaultDacl, DaclLength, &DaclLength ); } else { Status = STATUS_NO_MEMORY; } NtClose(Token); if (!NT_SUCCESS(Status)) { CsrUnlockProcess(Process); LdrUnloadDll( ModuleHandle ); return (ULONG)Status; } } else { NtClose(Token); } ThreadAttributes.nLength = sizeof(ThreadAttributes); RtlCreateSecurityDescriptor(&SecurityDescriptor,SECURITY_DESCRIPTOR_REVISION1); ThreadAttributes.lpSecurityDescriptor = &SecurityDescriptor; SecurityDescriptor.Control = SE_DACL_PRESENT; SecurityDescriptor.Dacl = lpDefaultDacl->DefaultDacl; ThreadAttributes.bInheritHandle = FALSE; CsrUnlockProcess(Process); } #if DEVL } #endif // DEVL // // Set up the specified user-interface as the debugger of the // target process. Whip through the target process and // suspend all threads. Then Send CreateProcess, LoadModule, and // CreateThread Messages. Finally send the attach complete // exception. // Status = CsrDebugProcess( a->dwProcessId, &a->DebuggerClientId, (PCSR_ATTACH_COMPLETE_ROUTINE)a->AttachCompleteRoutine ); #if DEVL if (a->dwProcessId != -1) { #endif // DEVL if ( NT_SUCCESS(Status) ) { Thread = (PVOID)(CreateRemoteThreadRoutine)(ProcessHandle, &ThreadAttributes, 0L, (LPTHREAD_START_ROUTINE)a->AttachCompleteRoutine, 0, 0, &ThreadId ); LdrUnloadDll( ModuleHandle ); if ( lpDefaultDacl != &DefaultDacl ) { RtlFreeHeap(RtlProcessHeap(), 0,lpDefaultDacl); } if ( !Thread ) { return (ULONG)STATUS_UNSUCCESSFUL; } NtClose(Thread); } #if DEVL } #endif // DEVL return (ULONG) Status; }
int ConvertOutputToOem( IN UINT Codepage, IN LPWSTR Source, IN int SourceLength, // in chars OUT LPSTR Target, IN int TargetLength // in chars ) /* Converts SourceLength Unicode characters from Source into not more than TargetLength Codepage characters at Target. Returns the number characters put in Target. (0 if failure) */ { if (Codepage == OEMCP) { NTSTATUS Status; ULONG Length; // Can do this in place Status = RtlUnicodeToOemN(Target, TargetLength, &Length, Source, SourceLength * sizeof(WCHAR) ); if (NT_SUCCESS(Status)) { return Length; } else { return 0; } } else { ASSERT (Source != (LPWSTR)Target); #ifdef SOURCE_EQ_TARGET LPSTR pszDestTmp; CHAR StackBuffer[STACK_BUFFER_SIZE]; DBGCHARS(("ConvertOutputToOem U->%d %.*ls\n", Codepage, SourceLength > 10 ? 10 : SourceLength, Source)); if (TargetLength > STACK_BUFFER_SIZE) { pszDestTmp = (LPSTR)HeapAlloc(pConHeap,MAKE_TAG( TMP_TAG ),TargetLength); if (pszDestTmp == NULL) { return 0; } } else { pszDestTmp = StackBuffer; } TargetLength = WideCharToMultiByte(Codepage, 0, Source, SourceLength, pszDestTmp, TargetLength, NULL, NULL); RtlCopyMemory(Target, pszDestTmp, TargetLength); if (pszDestTmp != StackBuffer) { HeapFree(pConHeap,0,pszDestTmp); } return TargetLength; #else DBGCHARS(("ConvertOutputToOem U->%d %.*ls\n", Codepage, SourceLength > 10 ? 10 : SourceLength, Source)); return WideCharToMultiByte(Codepage, 0, Source, SourceLength, Target, TargetLength, NULL, NULL); #endif } }
VOID * BackupAlloc(DWORD cb) { return(RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( BACKUP_TAG ), cb)); }
NTSTATUS AllocateConsole( IN HANDLE ConsoleHandle, IN LPWSTR Title, IN USHORT TitleLength, IN HANDLE ClientProcessHandle, OUT PHANDLE StdIn, OUT PHANDLE StdOut, OUT PHANDLE StdErr, OUT PCONSOLE_PER_PROCESS_DATA ProcessData, IN OUT PCONSOLE_INFO ConsoleInfo, IN BOOLEAN WindowVisible, IN DWORD dwConsoleThreadId, IN HDESK Desktop ) /*++ Routine Description: This routine allocates and initialized a console and its associated data - input buffer and screen buffer. Arguments: ConsoleHandle - Handle of console to allocate. dwWindowSize - Initial size of screen buffer window, in rows and columns. nFont - Initial number of font text is displayed in. dwScreenBufferSize - Initial size of screen buffer, in rows and columns. nInputBufferSize - Initial size of input buffer, in events. dwWindowFlags - StdIn - On return, contains handle to stdin. StdOut - On return, contains handle to stdout. StdErr - On return, contains handle to stderr. ProcessData - On return, contains the initialized per-process data. Return Value: Note: The console handle table lock must be held when calling this routine. --*/ { PCONSOLE_INFORMATION Console; NTSTATUS Status; BOOL Success; // // allocate console data // Console = (PCONSOLE_INFORMATION)HeapAlloc(pConHeap, MAKE_TAG( CONSOLE_TAG ) | HEAP_ZERO_MEMORY, sizeof(CONSOLE_INFORMATION)); if (Console == NULL) { return STATUS_NO_MEMORY; } ConsoleHandles[IndexFromHandle(ConsoleHandle)] = Console; Console->Flags = WindowVisible ? 0 : CONSOLE_NO_WINDOW; Console->hIcon = ConsoleInfo->hIcon; Console->iIconId = ConsoleInfo->iIconId; Console->dwHotKey = ConsoleInfo->dwHotKey; Console->CP = OEMCP; Console->OutputCP = ConsoleOutputCP; Console->ReserveKeys = CONSOLE_NOSHORTCUTKEY; Console->ConsoleHandle = ConsoleHandle; Console->bIconInit = TRUE; Console->VerticalClientToWindow = VerticalClientToWindow; Console->HorizontalClientToWindow = HorizontalClientToWindow; // // must wait for window to be destroyed or client impersonation won't // work. // Status = NtDuplicateObject(NtCurrentProcess(), CONSOLE_CLIENTTHREADHANDLE(CSR_SERVER_QUERYCLIENTTHREAD()), NtCurrentProcess(), &Console->ClientThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) { goto ErrorExit5; } #if DBG // // Make sure the handle isn't protected so we can close it later // UnProtectHandle(Console->ClientThreadHandle); #endif // DBG InitializeListHead(&Console->OutputQueue); InitializeListHead(&Console->ProcessHandleList); InitializeListHead(&Console->ExeAliasList); Status = NtCreateEvent(&Console->InitEvents[INITIALIZATION_SUCCEEDED], EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE); if (!NT_SUCCESS(Status)) { goto ErrorExit4a; } Status = NtCreateEvent(&Console->InitEvents[INITIALIZATION_FAILED], EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE); if (!NT_SUCCESS(Status)) { goto ErrorExit4; } Status = RtlInitializeCriticalSection(&Console->ConsoleLock); if (!NT_SUCCESS(Status)) { goto ErrorExit3a; } InitializeConsoleCommandData(Console); // // initialize input buffer // Status = CreateInputBuffer(ConsoleInfo->nInputBufferSize, &Console->InputBuffer); if (!NT_SUCCESS(Status)) { goto ErrorExit3; } Console->Title = (PWCHAR)HeapAlloc(pConHeap,MAKE_TAG( TITLE_TAG ),TitleLength+sizeof(WCHAR)); if (Console->Title == NULL) { Status = STATUS_NO_MEMORY; goto ErrorExit2; } RtlCopyMemory(Console->Title,Title,TitleLength); Console->Title[TitleLength/sizeof(WCHAR)] = (WCHAR)0; // NULL terminate Console->TitleLength = TitleLength; Console->OriginalTitle = (PWCHAR)HeapAlloc(pConHeap,MAKE_TAG( TITLE_TAG ),TitleLength+sizeof(WCHAR)); if (Console->OriginalTitle == NULL) { Status = STATUS_NO_MEMORY; goto ErrorExit1; } RtlCopyMemory(Console->OriginalTitle,Title,TitleLength); Console->OriginalTitle[TitleLength/sizeof(WCHAR)] = (WCHAR)0; // NULL terminate Console->OriginalTitleLength = TitleLength; Status = NtCreateEvent(&Console->TerminationEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE); if (!NT_SUCCESS(Status)) { goto ErrorExit1a; } // // initialize screen buffer. we don't call OpenConsole to do this // because we need to specify the font, windowsize, etc. // Status = DoCreateScreenBuffer(Console, ConsoleInfo, Console->Title); if (!NT_SUCCESS(Status)) { goto ErrorExit1b; } Console->CurrentScreenBuffer = Console->ScreenBuffers; Status = InitializeIoHandleTable(Console, ProcessData, StdIn, StdOut, StdErr ); if (!NT_SUCCESS(Status)) { goto ErrorExit0; } // // map event handles // if (!MapHandle(ClientProcessHandle, Console->InitEvents[INITIALIZATION_SUCCEEDED], &ConsoleInfo->InitEvents[INITIALIZATION_SUCCEEDED] )) { Status = STATUS_NO_MEMORY; goto ErrorExit0; } if (!MapHandle(ClientProcessHandle, Console->InitEvents[INITIALIZATION_FAILED], &ConsoleInfo->InitEvents[INITIALIZATION_FAILED] )) { Status = STATUS_NO_MEMORY; goto ErrorExit0; } if (!MapHandle(ClientProcessHandle, Console->InputBuffer.InputWaitEvent, &ConsoleInfo->InputWaitHandle )) { Status = STATUS_NO_MEMORY; goto ErrorExit0; } Success = PostThreadMessage(dwConsoleThreadId, CM_CREATE_CONSOLE_WINDOW, (DWORD)Console, (LONG)ClientProcessHandle ); if (!Success) { KdPrint(("CONSRV: PostThreadMessage failed %d\n",GetLastError())); Status = STATUS_UNSUCCESSFUL; goto ErrorExit0; } return STATUS_SUCCESS; ErrorExit0: Console->ScreenBuffers->RefCount = 0; FreeScreenBuffer(Console->ScreenBuffers); ErrorExit1b: NtClose(Console->TerminationEvent); ErrorExit1a: HeapFree(pConHeap,0,Console->OriginalTitle); ErrorExit1: HeapFree(pConHeap,0,Console->Title); ErrorExit2: Console->InputBuffer.RefCount = 0; FreeInputBuffer(&Console->InputBuffer); ErrorExit3: RtlDeleteCriticalSection(&Console->ConsoleLock); ErrorExit3a: NtClose(Console->InitEvents[INITIALIZATION_FAILED]); ErrorExit4: NtClose(Console->InitEvents[INITIALIZATION_SUCCEEDED]); ErrorExit4a: NtClose(Console->ClientThreadHandle); ErrorExit5: HeapFree(pConHeap,0,Console); return Status; }
NTSTATUS ConsoleAddProcessRoutine( IN PCSR_PROCESS ParentProcess, IN PCSR_PROCESS Process ) { PCONSOLE_PER_PROCESS_DATA ProcessData, ParentProcessData; PCONSOLE_INFORMATION Console; PCONSOLE_PROCESS_HANDLE ProcessHandleRecord; NTSTATUS Status = STATUS_SUCCESS; ProcessData = CONSOLE_FROMPROCESSPERPROCESSDATA(Process); ProcessData->HandleTablePtr = ProcessData->HandleTable; ProcessData->HandleTableSize = CONSOLE_INITIAL_IO_HANDLES; CONSOLE_SETCONSOLEAPPFROMPROCESSDATA(ProcessData,FALSE); if (ParentProcess) { ProcessData->RootProcess = FALSE; ParentProcessData = CONSOLE_FROMPROCESSPERPROCESSDATA(ParentProcess); // // If both the parent and new processes are console apps, // inherit handles from the parent process. // if (ParentProcessData->ConsoleHandle != NULL && (Process->Flags & CSR_PROCESS_CONSOLEAPP)) { LockConsoleHandleTable(); if (!(NT_SUCCESS(DereferenceConsoleHandle(ParentProcessData->ConsoleHandle, &Console)))) { ProcessData->ConsoleHandle = NULL; UnlockConsoleHandleTable(); return STATUS_PROCESS_IS_TERMINATING; } // // Don't add the process if the console is being shutdown. // LockConsole(Console); if (Console->Flags & CONSOLE_SHUTTING_DOWN) { Status = STATUS_PROCESS_IS_TERMINATING; ProcessHandleRecord = NULL; } else { ProcessHandleRecord = HeapAlloc(pConHeap,MAKE_TAG( HANDLE_TAG ),sizeof(CONSOLE_PROCESS_HANDLE)); if (ProcessHandleRecord == NULL) { Status = STATUS_NO_MEMORY; } else { // // duplicate parent's handle table // ASSERT(ProcessData->Foo == 0xF00); Status = InheritIoHandleTable(ProcessData, ParentProcess); if (NT_SUCCESS(Status)) { ProcessHandleRecord->Process = Process; ProcessHandleRecord->CtrlRoutine = NULL; ProcessHandleRecord->PropRoutine = NULL; AddProcessToList(Console,ProcessHandleRecord,Process->ProcessHandle); // // increment console reference count // Console->RefCount++; } else { HeapFree(pConHeap, 0, ProcessHandleRecord); } } } if (!NT_SUCCESS(Status)) { ProcessData->ConsoleHandle = NULL; } UnlockConsole(Console); UnlockConsoleHandleTable(); } else ProcessData->ConsoleHandle = NULL; } else { ProcessData->ConsoleHandle = NULL; } return Status; }
ULONG CreateSecurityDescriptor( ULONG *pSecurityDescriptor, PSID *ppWorldSid, ACCESS_MASK AccessMask) { ULONG rc = 0L; /* return code */ PACL pAclBuffer; /* ptr to ACL buffer */ ULONG SidLength; /* length of SID - 1 sub authority */ PSID pWSid; /* ptr to world SID */ SID_IDENTIFIER_AUTHORITY SidAuth = SECURITY_WORLD_SID_AUTHORITY; /* * Create World SID. */ SidLength = RtlLengthRequiredSid(1); if ((pWSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ) | HEAP_ZERO_MEMORY, SidLength)) == NULL) { *ppWorldSid = NULL; KdPrint(("NLSAPI (BaseSrv): Could NOT Allocate SID Buffer.\n")); return (ERROR_OUTOFMEMORY); } *ppWorldSid = pWSid; RtlInitializeSid(pWSid, &SidAuth, 1); *(RtlSubAuthoritySid(pWSid, 0)) = SECURITY_WORLD_RID; /* * Initialize Security Descriptor. */ rc = RtlCreateSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(rc)) { KdPrint(("NLSAPI (BaseSrv): Could NOT Create Security Descriptor - %lx.\n", rc)); RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid); return (rc); } /* * Initialize ACL. */ pAclBuffer = (PACL)((PBYTE)pSecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH); rc = RtlCreateAcl((PACL)pAclBuffer, MAX_PATH_LEN * sizeof(ULONG), ACL_REVISION2); if (!NT_SUCCESS(rc)) { KdPrint(("NLSAPI (BaseSrv): Could NOT Create ACL - %lx.\n", rc)); RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid); return (rc); } /* * Add an ACE to the ACL that allows World GENERIC_READ to the * section object. */ rc = RtlAddAccessAllowedAce((PACL)pAclBuffer, ACL_REVISION2, AccessMask, pWSid); if (!NT_SUCCESS(rc)) { KdPrint(("NLSAPI (BaseSrv): Could NOT Add Access Allowed ACE - %lx.\n", rc)); RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid); return (rc); } /* * Assign the DACL to the security descriptor. */ rc = RtlSetDaclSecurityDescriptor((PSECURITY_DESCRIPTOR)pSecurityDescriptor, (BOOLEAN)TRUE, (PACL)pAclBuffer, (BOOLEAN)FALSE); if (!NT_SUCCESS(rc)) { KdPrint(("NLSAPI (BaseSrv): Could NOT Set DACL Security Descriptor - %lx.\n", rc)); RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid); return (rc); } /* * Return success. */ return (NO_ERROR); }
/* * Returns bit combination * FE_ABANDONFONT - do not continue enumerating this font * FE_FONTOK - font was created and added to cache or already there */ int CALLBACK FontEnum( LPENUMLOGFONTW lpLogFont, LPNEWTEXTMETRICW lpTextMetric, int nFontType, LPARAM lParam ) /*++ Is called exactly once by GDI for each font in the system. This routine is used to store the FONT_INFO structure. --*/ { PFONTENUMDC pfed = (PFONTENUMDC)lParam; HDC hDC = pfed->hDC; BOOL bFindFaces = pfed->bFindFaces; HFONT hFont; TEXTMETRICW tmi; LONG nFont; LONG nFontNew; COORD SizeToShow; COORD SizeActual; COORD SizeWant; BYTE tmFamily; SIZE Size; LPWSTR pwszFace = lpLogFont->elfLogFont.lfFaceName; PFACENODE pFN; DBGFONTS((" FontEnum \"%ls\" (%d,%d) weight 0x%lx(%d) -- %s\n", pwszFace, lpLogFont->elfLogFont.lfWidth, lpLogFont->elfLogFont.lfHeight, lpLogFont->elfLogFont.lfWeight, lpLogFont->elfLogFont.lfWeight, bFindFaces ? "Finding Faces" : "Creating Fonts")); // // reject variable width and italic fonts, also tt fonts with neg ac // also reject DBCS fonts because they are never really fixed pitch // they can be "binary" pitch meaning SBCS widths are the same as all // other SBCS widths and DBCS widhts the same as all DBCS widhts // (but DBCS widths won't be the same as SBCS widths) if ( !(lpLogFont->elfLogFont.lfPitchAndFamily & FIXED_PITCH) || (lpLogFont->elfLogFont.lfItalic) || !(((NTMW_INTERNAL *)lpTextMetric)->tmd.fl & TMD_NONNEGATIVE_AC) || (IS_ANY_DBCS_CHARSET(lpLogFont->elfLogFont.lfCharSet)) ) { DBGFONTS((" REJECT face (variable pitch, italic, or neg a&c)\n")); return bFindFaces ? TRUE : FALSE; // unsuitable font } if (nFontType == TRUETYPE_FONTTYPE) { lpLogFont->elfLogFont.lfHeight = pfed->TTPointSize; lpLogFont->elfLogFont.lfWidth = 0; lpLogFont->elfLogFont.lfWeight = FW_NORMAL; } /* * reject TT fonts for whoom family is not modern, that is do not use * FF_DONTCARE // may be surprised unpleasantly * FF_DECORATIVE // likely to be symbol fonts * FF_SCRIPT // cursive, inappropriate for console * FF_SWISS OR FF_ROMAN // variable pitch */ if ((nFontType == TRUETYPE_FONTTYPE) && ((lpLogFont->elfLogFont.lfPitchAndFamily & 0xf0) != FF_MODERN)) { DBGFONTS((" REJECT face (TT but not FF_MODERN)\n")); return bFindFaces ? TRUE : FALSE; // unsuitable font } /* * reject non-TT fonts that aren't OEM */ if ((nFontType != TRUETYPE_FONTTYPE) && (lpLogFont->elfLogFont.lfCharSet != OEM_CHARSET)) { DBGFONTS((" REJECT face (not TT nor OEM)\n")); return bFindFaces ? TRUE : FALSE; // unsuitable font } /* * Add or find the facename */ pFN = AddFaceNode(&gpFaceNames, pwszFace); if (pFN == NULL) { return FALSE; } if (bFindFaces) { if (nFontType == TRUETYPE_FONTTYPE) { DBGFONTS(("NEW TT FACE %ls\n", pwszFace)); pFN->dwFlag |= EF_TTFONT; } else if (nFontType == RASTER_FONTTYPE) { DBGFONTS(("NEW OEM FACE %ls\n",pwszFace)); pFN->dwFlag |= EF_OEMFONT; } return 0; } if (IS_BOLD(lpLogFont->elfLogFont.lfWeight)) { DBGFONTS2((" A bold font (weight %d)\n", lpLogFont->elfLogFont.lfWeight)); // return 0; } /* get font info */ SizeWant.Y = (SHORT)lpLogFont->elfLogFont.lfHeight; SizeWant.X = (SHORT)lpLogFont->elfLogFont.lfWidth; CreateBoldFont: lpLogFont->elfLogFont.lfQuality = NONANTIALIASED_QUALITY; hFont = CreateFontIndirectW(&lpLogFont->elfLogFont); ASSERT(hFont); if (!hFont) { DBGFONTS((" REJECT font (can't create)\n")); return 0; // same font in other sizes may still be suitable } DBGFONTS2((" hFont = %lx\n", hFont)); // // for reasons unbeknownst to me, removing this code causes GDI // to yack, claiming that the font is owned by another process. // SelectObject(hDC,hFont); if (!GetTextMetricsW(hDC, &tmi)) { tmi = *((LPTEXTMETRICW)lpTextMetric); } if (GetTextExtentPoint32W(hDC, L"0", 1, &Size)) { SizeActual.X = (SHORT)Size.cx; } else { SizeActual.X = (SHORT)(tmi.tmMaxCharWidth); } SizeActual.Y = (SHORT)(tmi.tmHeight + tmi.tmExternalLeading); DBGFONTS2((" actual size %d,%d\n", SizeActual.X, SizeActual.Y)); tmFamily = tmi.tmPitchAndFamily; if (TM_IS_TT_FONT(tmFamily) && (SizeWant.Y >= 0)) { SizeToShow = SizeWant; if (SizeWant.X == 0) { // Asking for zero width height gets a default aspect-ratio width // It's better to show that width rather than 0. SizeToShow.X = SizeActual.X; } } else { SizeToShow = SizeActual; } DBGFONTS2((" SizeToShow = (%d,%d), SizeActual = (%d,%d)\n", SizeToShow.X, SizeToShow.Y, SizeActual.X, SizeActual.Y)); // there's a GDI bug - this assert fails occasionally //ASSERT (tmi.tmw.tmMaxCharWidth == lpTextMetric->tmMaxCharWidth); /* * NOW, determine whether this font entry has already been cached * LATER : it may be possible to do this before creating the font, if * we can trust the dimensions & other info from lpTextMetric. * Sort by size: * 1) By pixelheight (negative Y values) * 2) By height (as shown) * 3) By width (as shown) */ for (nFont = 0; nFont < (LONG)NumberOfFonts; ++nFont) { COORD SizeShown; if (FontInfo[nFont].hFont == NULL) { DBGFONTS(("! Font %x has a NULL hFont\n", nFont)); continue; } if (FontInfo[nFont].SizeWant.X > 0) { SizeShown.X = FontInfo[nFont].SizeWant.X; } else { SizeShown.X = FontInfo[nFont].Size.X; } if (FontInfo[nFont].SizeWant.Y > 0) { // This is a font specified by cell height. SizeShown.Y = FontInfo[nFont].SizeWant.Y; } else { SizeShown.Y = FontInfo[nFont].Size.Y; if (FontInfo[nFont].SizeWant.Y < 0) { // This is a TT font specified by character height. if (SizeWant.Y < 0 && SizeWant.Y > FontInfo[nFont].SizeWant.Y) { // Requested pixelheight is smaller than this one. DBGFONTS(("INSERT %d pt at %x, before %d pt\n", -SizeWant.Y, nFont, -FontInfo[nFont].SizeWant.Y)); nFontNew = nFont; goto InsertNewFont; } } } // DBGFONTS((" SizeShown(%x) = (%d,%d)\n",nFont,SizeShown.X,SizeShown.Y)); if (SIZE_EQUAL(SizeShown, SizeToShow) && FontInfo[nFont].Family == tmFamily && FontInfo[nFont].Weight == tmi.tmWeight && wcscmp(FontInfo[nFont].FaceName, pwszFace) == 0) { /* * Already have this font */ DBGFONTS2((" Already have the font\n")); DeleteObject(hFont); pfed->ulFE |= FE_FONTOK; return TRUE; } if ((SizeToShow.Y < SizeShown.Y) || (SizeToShow.Y == SizeShown.Y && SizeToShow.X < SizeShown.X)) { /* * This new font is smaller than nFont */ DBGFONTS(("INSERT at %x, SizeToShow = (%d,%d)\n", nFont, SizeToShow.X,SizeToShow.Y)); nFontNew = nFont; goto InsertNewFont; } } /* * The font we are adding should be appended to the list, * since it is bigger (or equal) to the last one. */ nFontNew = (LONG)NumberOfFonts; InsertNewFont: // at nFontNew // ASSERT ((lpTextMetric->tmPitchAndFamily & 1) == 0); /* If we have to grow our font table, do it */ if (NumberOfFonts == FontInfoLength) { PFONT_INFO Temp; FontInfoLength += FONT_INCREMENT; Temp = (PFONT_INFO)HeapReAlloc(pConHeap,MAKE_TAG( FONT_TAG ),FontInfo,sizeof(FONT_INFO) * FontInfoLength); ASSERT(Temp); if (Temp == NULL) { FontInfoLength -= FONT_INCREMENT; return FALSE; } FontInfo = Temp; } if (nFontNew < (LONG)NumberOfFonts) { RtlMoveMemory(&FontInfo[nFontNew+1], &FontInfo[nFontNew], sizeof(FONT_INFO)*(NumberOfFonts - nFontNew)); } /* * Store the font info */ FontInfo[nFontNew].hFont = hFont; FontInfo[nFontNew].Family = tmFamily; FontInfo[nFontNew].Size = SizeActual; if (TM_IS_TT_FONT(tmFamily)) { FontInfo[nFontNew].SizeWant = SizeWant; } else { FontInfo[nFontNew].SizeWant.X = 0; FontInfo[nFontNew].SizeWant.Y = 0; } FontInfo[nFontNew].Weight = tmi.tmWeight; FontInfo[nFont].FaceName = pFN->awch; ++NumberOfFonts; if (nFontType == TRUETYPE_FONTTYPE && !IS_BOLD(FontInfo[nFontNew].Weight)) { lpLogFont->elfLogFont.lfWeight = FW_BOLD; goto CreateBoldFont; } pfed->ulFE |= FE_FONTOK; // and continue enumeration return TRUE; }
QFontEngineMac::QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine) : fontID(fontID), multiEngine(multiEngine), cmap(0), symbolCMap(false) { fontDef = def; ATSUCreateAndCopyStyle(baseStyle, &style); ATSFontRef atsFont = FMGetATSFontRefFromFont(fontID); cgFont = CGFontCreateWithPlatformFont(&atsFont); const int maxAttributeCount = 4; ATSUAttributeTag tags[maxAttributeCount + 1]; ByteCount sizes[maxAttributeCount + 1]; ATSUAttributeValuePtr values[maxAttributeCount + 1]; int attributeCount = 0; synthesisFlags = 0; quint16 macStyle = 0; { uchar data[4]; ByteCount len = 4; if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr) macStyle = qFromBigEndian<quint16>(data); } Boolean atsuBold = false; Boolean atsuItalic = false; if (fontDef.weight >= QFont::Bold) { if (!(macStyle & 1)) { synthesisFlags |= SynthesizedBold; atsuBold = true; tags[attributeCount] = kATSUQDBoldfaceTag; sizes[attributeCount] = sizeof(atsuBold); values[attributeCount] = &atsuBold; ++attributeCount; } } if (fontDef.style != QFont::StyleNormal) { if (!(macStyle & 2)) { synthesisFlags |= SynthesizedItalic; atsuItalic = true; tags[attributeCount] = kATSUQDItalicTag; sizes[attributeCount] = sizeof(atsuItalic); values[attributeCount] = &atsuItalic; ++attributeCount; } } tags[attributeCount] = kATSUFontTag; values[attributeCount] = &fontID; sizes[attributeCount] = sizeof(fontID); ++attributeCount; Q_ASSERT(attributeCount < maxAttributeCount + 1); OSStatus err = ATSUSetAttributes(style, attributeCount, tags, sizes, values); Q_ASSERT(err == noErr); Q_UNUSED(err); quint16 tmpFsType; if (ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 8, 2, &tmpFsType, 0) == noErr) fsType = qFromBigEndian<quint16>(tmpFsType); else fsType = 0; }
NTSTATUS EnumerateFonts( DWORD Flags) { TEXTMETRIC tmi; HDC hDC; PFACENODE pFN; ULONG ulOldEnumFilter; DWORD FontIndex; DWORD dwFontType = 0; DBGFONTS(("EnumerateFonts %lx\n", Flags)); dwFontType = (EF_TTFONT|EF_OEMFONT|EF_DEFFACE) & Flags; if (FontInfo == NULL) { // // allocate memory for the font array // NumberOfFonts = 0; FontInfo = (PFONT_INFO)HeapAlloc(pConHeap,MAKE_TAG( FONT_TAG ),sizeof(FONT_INFO) * INITIAL_FONTS); if (FontInfo == NULL) return STATUS_NO_MEMORY; FontInfoLength = INITIAL_FONTS; } hDC = CreateDCW(L"DISPLAY",NULL,NULL,NULL); // Before enumeration, turn off font enumeration filters. ulOldEnumFilter = SetFontEnumeration(0); // restore all the other flags SetFontEnumeration(ulOldEnumFilter & ~FE_FILTER_TRUETYPE); if (Flags & EF_DEFFACE) { SelectObject(hDC,GetStockObject(OEM_FIXED_FONT)); if (GetTextMetricsW(hDC, &tmi)) { DefaultFontSize.X = (SHORT)(tmi.tmMaxCharWidth); DefaultFontSize.Y = (SHORT)(tmi.tmHeight+tmi.tmExternalLeading); DefaultFontFamily = tmi.tmPitchAndFamily; } GetTextFaceW(hDC, LF_FACESIZE, DefaultFaceName); DBGFONTS(("Default (OEM) Font %ls (%d,%d)\n", DefaultFaceName, DefaultFontSize.X, DefaultFontSize.Y)); // Make sure we are going to enumerate the OEM face. pFN = AddFaceNode(&gpFaceNames, DefaultFaceName); pFN->dwFlag |= EF_DEFFACE | EF_OEMFONT; } // Use DoFontEnum to get all fonts from the system. Our FontEnum // proc puts just the ones we want into an array // for (pFN = gpFaceNames; pFN; pFN = pFN->pNext) { DBGFONTS(("\"%ls\" is %s%s%s%s%s%s\n", pFN->awch, pFN->dwFlag & EF_NEW ? "NEW " : " ", pFN->dwFlag & EF_OLD ? "OLD " : " ", pFN->dwFlag & EF_ENUMERATED ? "ENUMERATED " : " ", pFN->dwFlag & EF_OEMFONT ? "OEMFONT " : " ", pFN->dwFlag & EF_TTFONT ? "TTFONT " : " ", pFN->dwFlag & EF_DEFFACE ? "DEFFACE " : " ")); if ((pFN->dwFlag & dwFontType) == 0) { // not the kind of face we want continue; } if (pFN->dwFlag & EF_ENUMERATED) { // we already enumerated this face continue; } DoFontEnum(hDC, pFN->awch, DefaultFontSize.Y); pFN->dwFlag |= EF_ENUMERATED; } // After enumerating fonts, restore the font enumeration filter. SetFontEnumeration(ulOldEnumFilter); DeleteDC(hDC); // Make sure the default font is set correctly if (NumberOfFonts > 0 && DefaultFontSize.X == 0 && DefaultFontSize.Y == 0) { DefaultFontSize.X = FontInfo[0].Size.X; DefaultFontSize.Y = FontInfo[0].Size.Y; DefaultFontFamily = FontInfo[0].Family; } for (FontIndex = 0; FontIndex < NumberOfFonts; FontIndex++) { if (FontInfo[FontIndex].Size.X == DefaultFontSize.X && FontInfo[FontIndex].Size.Y == DefaultFontSize.Y && FontInfo[FontIndex].Family == DefaultFontFamily) { break; } } ASSERT(FontIndex < NumberOfFonts); if (FontIndex < NumberOfFonts) { DefaultFontIndex = FontIndex; } else { DefaultFontIndex = 0; } DBGFONTS(("EnumerateFonts : DefaultFontIndex = %ld\n", DefaultFontIndex)); return STATUS_SUCCESS; }
ULONG SmpAllocateSessionId( IN PSMPKNOWNSUBSYS OwningSubsystem, IN PSMPKNOWNSUBSYS CreatorSubsystem OPTIONAL ) /*++ Routine Description: This function allocates a session id. Arguments: OwningSubsystem - Supplies the address of the subsystem that should become the owner of this session. CreatorSubsystem - An optional parameter that if supplied supplies the address of the subsystem requesting the creation of this session. This subsystem is notified when the session completes. Return Value: This function returns the session id for this session. --*/ { ULONG SessionId; PLIST_ENTRY SessionIdListInsertPoint; PSMPSESSION Session; RtlEnterCriticalSection(&SmpSessionListLock); // // SessionId's are allocated by incrementing a 32 bit counter. // If the counter wraps, then session id's are allocated by // scaning the sorted list of current session id's for a hole. // SessionId = SmpNextSessionId++; SessionIdListInsertPoint = SmpSessionListHead.Blink; if ( !SmpNextSessionIdScanMode ) { if ( SmpNextSessionId == 0 ) { // // We have used up 32 bits worth of session id's so // enable scan mode session id allocation. // SmpNextSessionIdScanMode = TRUE; } } else { // // Compute a session id by scanning the sorted session id list // until a whole is found. When an id is found, then save it, // and re-calculate the inster point. // DbgPrint("SMSS: SessionId's Wraped\n"); DbgBreakPoint(); } Session = RtlAllocateHeap(SmpHeap, MAKE_TAG( SM_TAG ), sizeof(SMPSESSION)); Session->SessionId = SessionId; Session->OwningSubsystem = OwningSubsystem; Session->CreatorSubsystem = CreatorSubsystem; InsertTailList(SessionIdListInsertPoint,&Session->SortedSessionIdListLinks); RtlLeaveCriticalSection(&SmpSessionListLock); return SessionId; }
VOID StoreSelection( IN PCONSOLE_INFORMATION Console ) /*++ StoreSelection - Store selection (if present) into the Clipboard --*/ { PCHAR_INFO Selection,CurCharInfo; COORD SourcePoint; COORD TargetSize; SMALL_RECT TargetRect; PWCHAR CurChar,CharBuf; HANDLE ClipboardDataHandle; SHORT i,j; BOOL Success; PSCREEN_INFORMATION ScreenInfo; BOOL bFalseUnicode; // // See if there is a selection to get // if (!(Console->SelectionFlags & CONSOLE_SELECTION_NOT_EMPTY)) { return; } // // read selection rectangle. clip it first. // ScreenInfo = Console->CurrentScreenBuffer; if (Console->SelectionRect.Left < 0) { Console->SelectionRect.Left = 0; } if (Console->SelectionRect.Top < 0) { Console->SelectionRect.Top = 0; } if (Console->SelectionRect.Right >= ScreenInfo->ScreenBufferSize.X) { Console->SelectionRect.Right = (SHORT)(ScreenInfo->ScreenBufferSize.X-1); } if (Console->SelectionRect.Bottom >= ScreenInfo->ScreenBufferSize.Y) { Console->SelectionRect.Bottom = (SHORT)(ScreenInfo->ScreenBufferSize.Y-1); } TargetSize.X = WINDOW_SIZE_X(&Console->SelectionRect); TargetSize.Y = WINDOW_SIZE_Y(&Console->SelectionRect); if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) { Selection = (PCHAR_INFO)HeapAlloc(pConHeap,MAKE_TAG( TMP_TAG ),sizeof(CHAR_INFO) * TargetSize.X * TargetSize.Y); if (Selection == NULL) return; #ifdef i386 if ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) && (Console->Flags & CONSOLE_VDM_REGISTERED)) { ReadRegionFromScreenHW(ScreenInfo, &Console->SelectionRect, Selection); } else { #endif SourcePoint.X = Console->SelectionRect.Left; SourcePoint.Y = Console->SelectionRect.Top; TargetRect.Left = TargetRect.Top = 0; TargetRect.Right = (SHORT)(TargetSize.X-1); TargetRect.Bottom = (SHORT)(TargetSize.Y-1); ReadRectFromScreenBuffer(ScreenInfo, SourcePoint, Selection, TargetSize, &TargetRect); #ifdef i386 } #endif // extra 2 per line is for CRLF, extra 1 is for null ClipboardDataHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (TargetSize.Y * (TargetSize.X + 2) + 1) * sizeof(WCHAR)); if (ClipboardDataHandle == NULL) { HeapFree(pConHeap,0,Selection); return; } // // convert to clipboard form // CurCharInfo = Selection; CurChar = CharBuf = GlobalLock(ClipboardDataHandle); bFalseUnicode = ((ScreenInfo->Flags & CONSOLE_OEMFONT_DISPLAY) && !(Console->FullScreenFlags & CONSOLE_FULLSCREEN)); for (i=0;i<TargetSize.Y;i++) { PWCHAR pwchLineStart = CurChar; for (j=0;j<TargetSize.X;j++,CurCharInfo++,CurChar++) { *CurChar = CurCharInfo->Char.UnicodeChar; if (*CurChar == 0) { *CurChar = UNICODE_SPACE; } } // trim trailing spaces CurChar--; while ((CurChar >= pwchLineStart) && (*CurChar == UNICODE_SPACE)) CurChar--; CurChar++; if (bFalseUnicode) { FalseUnicodeToRealUnicode(pwchLineStart, CurChar - pwchLineStart, Console->OutputCP); } *CurChar++ = UNICODE_CARRIAGERETURN; *CurChar++ = UNICODE_LINEFEED; } if (TargetSize.Y) CurChar -= 2; // don't put CRLF on last line *CurChar = '\0'; // null terminate GlobalUnlock(ClipboardDataHandle); HeapFree(pConHeap,0,Selection); Success = OpenClipboard(Console->hWnd); if (!Success) { GlobalFree(ClipboardDataHandle); return; } Success = EmptyClipboard(); if (!Success) { GlobalFree(ClipboardDataHandle); return; } SetClipboardData(CF_UNICODETEXT,ClipboardDataHandle); CloseClipboard(); // Close clipboard } else { HBITMAP hBitmapTarget, hBitmapOld; HDC hDCMem; HPALETTE hPaletteOld; int Height; NtWaitForSingleObject(ScreenInfo->BufferInfo.GraphicsInfo.hMutex, FALSE, NULL); hDCMem = CreateCompatibleDC(Console->hDC); hBitmapTarget = CreateCompatibleBitmap(Console->hDC, TargetSize.X, TargetSize.Y); if (hBitmapTarget) { hBitmapOld = SelectObject(hDCMem, hBitmapTarget); if (ScreenInfo->hPalette) { hPaletteOld = SelectPalette(hDCMem, ScreenInfo->hPalette, FALSE); } MyInvert(Console,&Console->SelectionRect); // if (DIB is a top-down) // ySrc = abs(height) - rect.bottom - 1; // else // ySrc = rect.Bottom. // Height = ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo->bmiHeader.biHeight; StretchDIBits(hDCMem, 0, 0, TargetSize.X, TargetSize.Y, Console->SelectionRect.Left + ScreenInfo->Window.Left, (Height < 0) ? -Height - (Console->SelectionRect.Bottom + ScreenInfo->Window.Top) - 1 : Console->SelectionRect.Bottom + ScreenInfo->Window.Top, TargetSize.X, TargetSize.Y, ScreenInfo->BufferInfo.GraphicsInfo.BitMap, ScreenInfo->BufferInfo.GraphicsInfo.lpBitMapInfo, ScreenInfo->BufferInfo.GraphicsInfo.dwUsage, SRCCOPY); MyInvert(Console,&Console->SelectionRect); if (ScreenInfo->hPalette) { SelectPalette(hDCMem, hPaletteOld, FALSE); } SelectObject(hDCMem, hBitmapOld); OpenClipboard(Console->hWnd); EmptyClipboard(); SetClipboardData(CF_BITMAP,hBitmapTarget); CloseClipboard(); } DeleteDC(hDCMem); NtReleaseMutant(ScreenInfo->BufferInfo.GraphicsInfo.hMutex, NULL); } }
static void initializeDb() { QFontDatabasePrivate *db = privateDb(); if(!db || db->count) return; #if defined(QT_MAC_USE_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0); if(!collection) return; QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection); if(!fonts) return; QString foundry_name = "CoreText"; const int numFonts = CFArrayGetCount(fonts); for(int i = 0; i < numFonts; ++i) { CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i); QCFString family_name = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL); QCFString style_name = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL); QtFontFamily *family = db->family(family_name, true); if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) { CFIndex length = CFArrayGetCount(languages); for (int i = 1; i < LanguageCount; ++i) { if (!languageForWritingSystem[i]) continue; QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII); if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang)) family->writingSystems[i] = QtFontFamily::Supported; } } QtFontFoundry *foundry = family->foundry(foundry_name, true); QtFontStyle::Key styleKey; QString styleName = style_name; if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) { if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) { Q_ASSERT(CFNumberIsFloatType(weight)); double d; if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) { //qDebug() << "BOLD" << (QString)family_name << d; styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal; } } if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) { Q_ASSERT(CFNumberIsFloatType(italic)); double d; if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) { //qDebug() << "ITALIC" << (QString)family_name << d; if (d > 0.0) styleKey.style = QFont::StyleItalic; } } } QtFontStyle *style = foundry->style(styleKey, styleName, true); style->smoothScalable = true; if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) { //qDebug() << "WHEE"; int pixel_size=0; if(CFNumberIsFloatType(size)) { double d; CFNumberGetValue(size, kCFNumberDoubleType, &d); pixel_size = d; } else { CFNumberGetValue(size, kCFNumberIntType, &pixel_size); } //qDebug() << "SIZE" << (QString)family_name << pixel_size; if(pixel_size) style->pixelSize(pixel_size, true); } else { //qDebug() << "WTF?"; } } } else #endif { #ifndef QT_MAC_USE_COCOA FMFontIterator it; if (!FMCreateFontIterator(0, 0, kFMUseGlobalScopeOption, &it)) { while (true) { FMFont fmFont; if (FMGetNextFont(&it, &fmFont) != noErr) break; FMFontFamily fmFamily; FMFontStyle fmStyle; QString familyName; QtFontStyle::Key styleKey; ATSFontRef atsFont = FMGetATSFontRefFromFont(fmFont); if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) { { //sanity check the font, and see if we can use it at all! --Sam ATSUFontID fontID; if(ATSUFONDtoFontID(fmFamily, 0, &fontID) != noErr) continue; } if (fmStyle & ::italic) styleKey.style = QFont::StyleItalic; if (fmStyle & ::bold) styleKey.weight = QFont::Bold; ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily); QCFString cfFamilyName;; ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName); familyName = cfFamilyName; } else { QCFString cfFontName; ATSFontGetName(atsFont, kATSOptionFlagsDefault, &cfFontName); familyName = cfFontName; quint16 macStyle = 0; { uchar data[4]; ByteCount len = 4; if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr) macStyle = qFromBigEndian<quint16>(data); } if (macStyle & 1) styleKey.weight = QFont::Bold; if (macStyle & 2) styleKey.style = QFont::StyleItalic; } QtFontFamily *family = db->family(familyName, true); QtFontFoundry *foundry = family->foundry(QString(), true); QtFontStyle *style = foundry->style(styleKey, QString(), true); style->pixelSize(0, true); style->smoothScalable = true; initWritingSystems(family, atsFont); } FMDisposeFontIterator(&it); } #endif } }
VOID DbgSsHandleKmApiMsg( IN PDBGKM_APIMSG ApiMsg, IN HANDLE ReplyEvent OPTIONAL ) /*++ Routine Description: This function is called by a subsystem upon receipt of a message whose type is LPC_DEBUG_EVENT. The purpose of this function is to propagate the debug event message to the debug server. A number of callouts are performed prior to propagating the message: - For all messages, the KmApiMsgFilter is called (if it was supplied during DbgSsInitialize. If this returns anything other that DBG_CONTINUE, the message is not propagated by this function. The caller is responsible for event propagation, and for replying to the thread reporting the debug event. - For create process messages, the UiLookupRoutine is called. If a success code is returned than message is propagated. Otherwise, a reply is generated to the thread reporting the debug event. - For create process and create thread messages, SubsystemKeyLookupRoutine is called. Failure does not effect propagation. It simply inhibits the update of messages SubSystemKey field. Based on the debug event type, a DBGSS_APIMSG is formated and sent as a datagram to the debug server. Arguments: ApiMsg - Supplies the debug event message to propagate to the debug server. ReplyEvent - An optional parameter, that if specified supplies a handle to an event that is to be signaled rather that generating a reply to this message. Return Value: None. --*/ { NTSTATUS st; CLIENT_ID DebugUiClientId; ULONG SubsystemKey; PDBGSS_CONTINUE_KEY ContinueKey; ApiMsg->ReturnedStatus = STATUS_PENDING; #if DBG && 0 if (ApiMsg->ApiNumber >= DbgKmMaxApiNumber ) { ApiMsg->ApiNumber = DbgKmMaxApiNumber; } DbgPrint( "DBG: %s Api Request received from %lx.%lx\n", DbgpKmApiName[ ApiMsg->ApiNumber ], ApiMsg->h.ClientId.UniqueProcess, ApiMsg->h.ClientId.UniqueThread ); #endif // DBG if (DbgSspKmApiMsgFilter) { if ( (DbgSspKmApiMsgFilter)(ApiMsg) != DBG_CONTINUE ) { return; } } ContinueKey = (PDBGSS_CONTINUE_KEY) RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( DBG_TAG ), sizeof(*ContinueKey)); if ( !ContinueKey ) { ApiMsg->ReturnedStatus = STATUS_NO_MEMORY; if ( ARGUMENT_PRESENT(ReplyEvent) ) { st = NtSetEvent(ReplyEvent,NULL); } else { st = NtReplyPort(DbgSspKmReplyPort, (PPORT_MESSAGE)ApiMsg ); } ASSERT(NT_SUCCESS(st)); return; } ContinueKey->KmApiMsg = *ApiMsg; ContinueKey->ReplyEvent = ReplyEvent; switch (ApiMsg->ApiNumber) { case DbgKmExceptionApi : st = DbgSspException( ContinueKey, &ApiMsg->h.ClientId, &ApiMsg->u.Exception ); break; case DbgKmCreateThreadApi : if ( DbgSspSubsystemKeyLookupRoutine ) { st = (DbgSspSubsystemKeyLookupRoutine)( &ApiMsg->h.ClientId, &SubsystemKey, FALSE ); if ( NT_SUCCESS(st) ) { ApiMsg->u.CreateThread.SubSystemKey = SubsystemKey; } } st = DbgSspCreateThread( ContinueKey, &ApiMsg->h.ClientId, &ApiMsg->u.CreateThread ); break; case DbgKmCreateProcessApi : st = (DbgSspUiLookUpRoutine)( &ApiMsg->h.ClientId, &DebugUiClientId ); if ( !NT_SUCCESS(st) ) { break; } if ( DbgSspSubsystemKeyLookupRoutine ) { st = (DbgSspSubsystemKeyLookupRoutine)( &ApiMsg->h.ClientId, &SubsystemKey, TRUE ); if ( NT_SUCCESS(st) ) { ApiMsg->u.CreateProcessInfo.SubSystemKey = SubsystemKey; } st = (DbgSspSubsystemKeyLookupRoutine)( &ApiMsg->h.ClientId, &SubsystemKey, FALSE ); if ( NT_SUCCESS(st) ) { ApiMsg->u.CreateProcessInfo.InitialThread.SubSystemKey = SubsystemKey; } } st = DbgSspCreateProcess( ContinueKey, &ApiMsg->h.ClientId, &DebugUiClientId, &ApiMsg->u.CreateProcessInfo ); break; case DbgKmExitThreadApi : st = DbgSspExitThread( ContinueKey, &ApiMsg->h.ClientId, &ApiMsg->u.ExitThread ); break; case DbgKmExitProcessApi : st = DbgSspExitProcess( ContinueKey, &ApiMsg->h.ClientId, &ApiMsg->u.ExitProcess ); break; case DbgKmLoadDllApi : st = DbgSspLoadDll( ContinueKey, &ApiMsg->h.ClientId, &ApiMsg->u.LoadDll ); break; case DbgKmUnloadDllApi : st = DbgSspUnloadDll( ContinueKey, &ApiMsg->h.ClientId, &ApiMsg->u.UnloadDll ); break; default : st = STATUS_NOT_IMPLEMENTED; } if ( !NT_SUCCESS(st) ) { ApiMsg->ReturnedStatus = st; RtlFreeHeap(RtlProcessHeap(), 0, ContinueKey); if ( ARGUMENT_PRESENT(ReplyEvent) ) { st = NtSetEvent(ReplyEvent,NULL); } else { st = NtReplyPort(DbgSspKmReplyPort, (PPORT_MESSAGE)ApiMsg ); } ASSERT(NT_SUCCESS(st)); } }