:: Visual Foxpro, Foxpro for DOS
Найти CRls
alex_lip
Автор

Сообщений: 74
Дата регистрации: 23.01.2006
Доброго времени суток.
Пытаюсь применить код
lnStoreProvider = CERT_STORE_PROV_SYSTEM
lcPara = STRCONV("MY" + CHR(0), 5)
hStoreHandle = CertOpenStore(lnStoreProvider, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, lcPara)
If !hStoreHandle = 0
pCertContext = 0
pCertContext = CertEnumCRLsInStore(hStoreHandle, pCertContext)
Do While !pCertContext = 0
szNameString = Replicate(Chr(0), MAX_NAME)
cchString = MAX_NAME && 256
nChars = CertGetNameStringA(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, 0, @m.szNameString, cchString)
Для того, чтобы найти все списки отзывов(CRLs), которые есть у данного пользователя.
для этого использую
lcPara = STRCONV("CA" + CHR(0), 5)
hStoreHandle = CertOpenStore(lnStoreProvider, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, lcPara)
pCertContext = CertEnumCRLsInStore(hStoreHandle, pCertContext)
Но в этом случае функция
nChars = CertGetNameStringA(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, 0, @m.szNameString, cchString)
Не отрабатывает.
Куда смотреть?
Ratings: 0 negative/0 positive
Re: Найти CRls
PaulWist

Сообщений: 14601
Дата регистрации: 01.04.2004
Посмотри forum.foxclub.ru


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Найти CRls
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
У списка отзыва есть только Issuer, и насколько я понимаю, простого АПИ для его извлечения нет - он там внутри структур спрятан...
А зачем это вообще понадобилось? Свой GUI управления сертификатами и всем прочим рисуешь?

Если что, CertEnumCRLsInStore() возвращает указатель на CRL_CONTEXT, а не на CERT_CONTEXT (поэтому бессмысленно далее пользоваться функциями работы с CERT_CONTEXT). В этой структуре есть указатель на структуру CRL_INFO, в ней есть поле Issuer с указателем на BLOB с данными о CA выпустившим данный СОС, текст из которого по идее вынимает функция CertNameToStr()...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Найти CRls
alex_lip
Автор

Сообщений: 74
Дата регистрации: 23.01.2006
Все правильно. Только у функций работы с сертификатами есть способ сразу в строку вытащить имя. А здесь я как раз с указателем на blob и потерялся. Мне издатель и нужен(issuer).
Я не знаю как на фоксе это сделать.....
Ratings: 0 negative/0 positive
Re: Найти CRls
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Как-то так. Хотя всё одно не пойму на кой чёрт это может быть нужно в фоксовой программе

#DEFINE CERT_CLOSE_STORE_FORCE_FLAG 1
#DEFINE CERT_CLOSE_STORE_CHECK_FLAG 2
#DEFINE CERT_STORE_PROV_SYSTEM 10
#DEFINE CERT_SYSTEM_STORE_LOCATION_SHIFT 16
#DEFINE CERT_SYSTEM_STORE_CURRENT_USER_ID 1
#DEFINE X509_ASN_ENCODING 1
#DEFINE CERT_SIMPLE_NAME_STR 1
#DEFINE CERT_OID_NAME_STR 2
#DEFINE CERT_X500_NAME_STR 3
DECLARE INTEGER GetLastError IN WIN32API
DECLARE INTEGER CertOpenStore IN crypt32.DLL INTEGER lpszStoreProvider, INTEGER dwMsgAndCertEncodingType, INTEGER hCryptProv, INTEGER dwFlags, STRING pvPara
DECLARE INTEGER CertCloseStore IN crypt32.DLL INTEGER hCertStore, INTEGER dwFlags
DECLARE INTEGER CertEnumCRLsInStore IN crypt32.DLL INTEGER hStoreHandle, INTEGER pCertContext
DECLARE INTEGER CertNameToStr IN crypt32.DLL INTEGER dwCertEncodingType, INTEGER pName, INTEGER dwStrType, STRING@ psz, INTEGER csz
CLEAR
LOCAL hStoreHandle, pCertContext, pCRLInfo, lnLen, lcBuf
hStoreHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, BITLSHIFT(CERT_SYSTEM_STORE_CURRENT_USER_ID, CERT_SYSTEM_STORE_LOCATION_SHIFT), STRCONV("CA"+CHR(0), 5))
IF m.hStoreHandle > 0
pCertContext = CertEnumCRLsInStore(m.hStoreHandle, 0)
DO WHILE m.pCertContext <> 0
pCRLInfo = CTOBIN(SYS(2600, m.pCertContext+12, 4), "4R")+2^31
lnLen = CertNameToStr(X509_ASN_ENCODING, m.pCRLInfo+16, CERT_X500_NAME_STR, .NULL., 0)
IF m.lnLen <> 0
lcBuf = SPACE(m.lnLen)
IF CertNameToStr(X509_ASN_ENCODING, m.pCRLInfo+16, CERT_X500_NAME_STR, @lcBuf, m.lnLen) = m.lnLen
? LEFT(m.lcBuf, m.lnLen - 1)
ELSE
? "Error retreiving CRL issuer. Error " + TRANSFORM(GetLastError(), "@0")
ENDIF
ELSE
? "Error retreiving CRL issuer length. Error " + TRANSFORM(GetLastError(), "@0")
ENDIF
pCertContext = CertEnumCRLsInStore (m.hStoreHandle, m.pCertContext)
ENDDO
IF CertCloseStore(m.hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG) = 0
? "Failed to close certificates storage. Error " + TRANSFORM(GetLastError(), "@0")
ENDIF
ELSE
? "Failed to open certificates storage. Error " + TRANSFORM(GetLastError(), "@0")
ENDIF


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Найти CRls
alex_lip
Автор

Сообщений: 74
Дата регистрации: 23.01.2006
Спасибо! Дело в том, что я в системе документооборота (на фоксе) проверяю наличие на компе корневого сертификата и списка отзывов, которые сам и выпускаю. Но расставляют эти сертификаты не я, а системщики. Которые иногда ленятся , иногда тупят. Надо контролировать ((
Ratings: 0 negative/0 positive
Re: Найти CRls
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Хммм если в этой системе ИСПОЛЬЗУЮТСЯ данные сертификаты, то по идее по возникновению ошибки при попытке подписать или проверить документ можно судить о том что "чего-то не хватает". Т.к. для правильного использования нужно:
- наличие всей цепочки сертификатов - и корневого, и промежуточного (если он есть, что как бы "хороший тон"), и собственно "пользовательского", используемого для подписи.
- наличие актуальных COC для корневого и промежуточного сертификатов - у СОС тоже есть "время жизни", точнее период, после которого требуется этот список обновить.

Кроме того есть подход вообще БЕЗ использования COC - с запросами текущего статуса сертификата у CA по протоколу OCSP. Он позволяет гораздо быстрее отзывать скомпрометированные сертификаты, и не требует муторного слежения за "актуальностью" СОС...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Найти CRls
alex_lip
Автор

Сообщений: 74
Дата регистрации: 23.01.2006
Мне не нужны списки отзывов реальные. Я и так через программу контролирую пользователей. Crl - просто заглушка чтобы подпись была действительна(он просто должен быть) . Подпись не является юридически значимой. Она используется только внутри организации. Я использую open-ssl и сам генерю и корневой и сертификаты пользователей. Из фоксы внутри формы я запускаю Word, а там уже пользователь средствами word подписывает документ. Потом сохраняет в Oracle blob. И документ хранится подписанный. Просто пользователей уже больше тысячи. Поэтому нужно отслеживать, чтобы у всех был установлен корневой сертификат и список отзывов для того чтобы при просмотре подпись была действительна.
Ratings: 0 negative/0 positive
Re: Найти CRls
alex_lip
Автор

Сообщений: 74
Дата регистрации: 23.01.2006
Кстати спасибо за наводку про OCSP. Это на будущее. Сейчас просто не хватает возможности все охватить. У меня полтора разработчика и полтора человека на поддержке.
Ratings: 0 negative/0 positive
Re: Найти CRls
rvc44

Сообщений: 2211
Откуда: Тамбов
Дата регистрации: 06.12.2005
Интересно, зачем при получении значения pCRLInfo в приведенном выше примере устанавливать старший бит путём добавления 2^31? Традиционно, если старший бит равен 1, то число считается отрицательным, только, если оно не определено как беззнаковое.

Ещё у меня какая-то засада приключилась с вызовом функции CryptoAPI CertFindExtension с параметром szOID_CRL_REASON_CODE для определения причины отзыва сертификата, при чтении информации из CRL, при передаче в нее параметров, предварительно полученных из структуры CRL_ENTRY. Почему-то эта функция у меня всегда возвращает ноль. При этом, информация о CRL Issuer и SerialNumber каждого из отозванных сертификатов у меня извлекается из загруженного CRL list вполне успешно на чистом фоксе. При получении SerialNumber, для его корректного отображения/сохранения приходится инвертировать порядок следования байт. Так что пока определяю только факт того, что сертификат отозван, без определения причины его отзыва, которую пока не удалось прочитать, что в принципе не критично. Возможно, кто-то из форумчан разобрался, как из VFP использовать функции CertFindExtension и CryptFormatObject для получения и отображения CRL Reason Code?

И последнее: кто как обходит Proxy при автоматической загрузке CRL из адреса(ов) CDP, указанных в сертификате? Я получаю настройки Proxy из настроек браузера IE в реестре. Но бывают случаи, когда пользователи браузер IE вообще не используют, либо применяется автоматический сценарий настройки Proxy без указания его адреса в явном виде. Просто интересно, кто как решает данную проблему, чтобы не запрашивать настройку Proxy у пользователя вручную?
Ratings: 0 negative/0 positive
Re: Найти CRls
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
rvc44
Интересно, зачем при получении значения pCRLInfo в приведенном выше примере устанавливать старший бит путём добавления 2^31? Традиционно, если старший бит равен 1, то число считается отрицательным, только, если оно не определено как беззнаковое.
Потому что конвертация 4 байт в число выполняется фоксовой функцией CTOBIN, а она несколько своеобразна при работе с беззнаковыми целыми - ну точнее она не умеет с ними работать (считает все dword за знаковые, и может лишь знаковый бит инвертировать, что мало поможет в данном случае), вот и приходится шаманить, чтобы получить правильный адрес (который, конечно же, есть число беззнаковое ).


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Найти CRls
rvc44

Сообщений: 2211
Откуда: Тамбов
Дата регистрации: 06.12.2005
Посмотрел сейчас еще раз свой код вызова CryptoAPI функции CertFindExtension с параметром szOID_CRL_REASON_CODE для определения причины отзыва сертификата. Оказывается, я сам себя ввел в заблуждение, поскольку это расширение не всегда присутствует! Ноль возвращается именно в тех случаях, когда указанное расширение отсутствует и ненулевое значение во всех остальных случаях. Таким образом, теперь осталось разобраться с параметрами функции CryptFormatObject и прикрутить её вызов, что постараюсь сделать в ближайшее время.
Ratings: 0 negative/0 positive
Re: Найти CRls
rvc44

Сообщений: 2211
Откуда: Тамбов
Дата регистрации: 06.12.2005
Спасибо за пояснение! Возьмем на вооружение данное полезное шаманство. Получается для CryptoAPI-функций при каждом CTOBIN можно использовать? Были случаи, когда отсутствие этой добавки приводили к неработоспособности кода?
Ratings: 0 negative/0 positive
Re: Найти CRls
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Без этой "добавки" код будет всегда некорректен Проявится это, конечно, лишь в случае если адрес окажется из верхнего диапазона памяти, т.е. будет больше чем 0x7fffffff
Это было не очень распространено в эпоху WinXP, т.к. 32 битная ОС при обычной клиентской установке резервировала верхнюю половину адресов под систему, и в принципе можно было применять CTOBIN(addr,"4RS"). Но в 64-битных системах (равно как и в некоторых "серверных" или "специальных" установках 32-битных систем - там есть специальный флажок управляющий этим поведением, в т.ч. даже в WinXP Prof он работает) 32-битный процесс уже может получить больше 2Гб памяти - до 3Гб в 32-битных системах и практически полный диапазон в 4Гб в 64-битных ОС. Правда ещё и сам процесс должен сообщить что он Large address aware, иначе система всё так же будет ограничивать его 2-мя ГБ "пользователькой" памяти.
Я не думаю что фокс поддерживает этот режим, но всё равно мне кажется что правильнее кодировать "правильно", а не с оглядкой на некоторое ограничение, позволяющее в ряде случаев трактовать адрес как знаковое число


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Найти CRls
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Не видел в диспетчере памяти обьема занимаемой памяти >= чем 2Г (видел, в VFP же, при явном занятии памяти через API, 1.7Г). И вообще, сам VFP повалится, если > 2г (задействовать 32й бит адреса в памяти), что-то было такое. Натыкался при разборе CSV-файла недействительных паспортов, 150млн записей, неслабый почин цифровизации нашего документооборота )
Ratings: 0 negative/0 positive
Re: Найти CRls
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Это не повод говнокодить
Указатели, сиречь адреса в памяти - это 32 разрядные БЕЗЗНАКОВЫЕ целые. Так их и следует трактовать.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Найти CRls
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Способ то давай, создать фоксовое Integer-число (чтобы его передать функции? зачем все это нужно?! параметры в АПИ все равно передаютмя как байты, можно передать любое значение сташего байта, и для этого не оьязателдьно использовать BINNOC и наоборотный его аналоu. Да, неудачный получился BINTOC

Доб. Так то просто, BITSET(0, 31), и то, за ним надо присматртивать.



Исправлено 1 раз(а). Последнее : of63, 01.09.19 22:03
Ratings: 0 negative/0 positive
Re: Найти CRls
rvc44

Сообщений: 2211
Откуда: Тамбов
Дата регистрации: 06.12.2005
Теперь, добившись работы функции CertFindExtension с параметром szOID_CRL_REASON_CODE, столкнулся со следующей проблемой при вызове функции CryptFormatObject.
Описание данной функции в MSDN следующее:
* The CryptFormatObject function formats the encoded data and returns a Unicode string in the allocated buffer according to the certificate encoding type.
BOOL CryptFormatObject(
DWORD dwCertEncodingType, && Type of encoding used on the certificate. The currently defined certificate encoding type used is X509_ASN_ENCODING.
DWORD dwFormatType, && Format type values. Not used. Set to zero.
DWORD dwFormatStrType, && Structure format type values. This parameter can be zero, or you can specify one or more of the following flags by using the bitwise-OR operator to combine them.
void *pFormatStruct, && A pointer to the format of the structure. Not used. Set to NULL.
LPCSTR lpszStructType, && A pointer to an OID that defines the encoded data. If the high-order word of the lpszStructType parameter is zero, the low-order word specifies the integer identifier for the type of the given structure. Otherwise, this parameter is a long pointer to a null-terminated string.
const BYTE *pbEncoded, && A pointer to the encoded data to be formatted. If lpszStructType is one of the OIDs listed above, the pbEncoded is the encoded extension.
DWORD cbEncoded, && The size, in bytes, of the pbEncoded structure.
void *pbFormat, && A pointer to a buffer that receives the formatted string. When the buffer that is specified is not large enough to receive the decoded structure, the function sets ERROR_MORE_DATA and stores the required buffer size, in bytes, into the variable pointed to by pcbFormat. This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.
DWORD *pcbFormat && A pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbFormat parameter. When the function returns, the variable pointed to by the pcbFormat parameter contains the number of bytes stored in the buffer. This parameter can be NULL, only if pbFormat is NULL.
);

Пробуем перевести описание функции на VFP:

DECLARE INTEGER CryptFormatObject IN crypt32;
LONG dwCertEncodingType,;
LONG dwFormatType,;
LONG dwFormatStrType,;
LONG @ pFormatStruct,;
STRING @ lpszStructType,; && LPCSTR lpszStructType - Указатель на строковый буфер, он может быть как STRING @, так и LONG, когда как удобнее!
STRING @ pbEncoded,; && Pointer to BYTE (const BYTE *pbEncoded)
LONG cbEncoded,;
STRING @ pbFormat,;
LONG @ pcbFormat

В 6-м и 7-м параметрах pbEncoded и cbEncoded передаётся по частям BLOB-объект, предварительно полученный в структуре CERT_EXTENSION:

* Структура CERT_EXTENSION определана в MSDN:
* hттps://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_extension
* hттp://msdn.microsoft.com/en-us/library/windows/desktop/aa377195%28v=vs.85%29.aspx
*|typedef struct _CERT_EXTENSION {
*| LPSTR pszObjId; 0:4
*| BOOL fCritical; 4:1 && 1 или всё-таки 4?
*| CRYPT_OBJID_BLOB Value; 5:8 && Сначала идёт Value.cbData, затем Value.pbData
*|} CERT_EXTENSION, *PCERT_EXTENSION;

Возник вопрос, а какой истиный размер total этой структуры в байтах? Он составляет 13 или 16 байт?
Элемент структуры BOOL fCritical кажется мне подозрительным!
Тип BOOL занимает всего один байт, в чем легко можно убедиться:

#include <iostream>
using namespace std;
int main () {
cout << sizeof(bool) << endl;
return 0;
}

Однако, во многих букварях написано, что если вы не упакуете структуру, она всегда будет иметь память, которая делится на размер слова (из-за выделения памяти).
Вы упаковываете структуру, используя __attribute__(packed) в gcc, например. Упаковка структуры может уменьшить требуемую память, но почти наверняка замедлит выполнение.
Поскольку в фоксе никто ничего не упаковывал, и с учетом информации от коллеги, который проверял в Delphi:

32 bit sizeof(pCertContext.pCertInfo.rgExtension^)=16
64 bit sizeof(pCertContext.pCertInfo.rgExtension^)=28

я уже начинаю сомневаться, что BYTE в структуре занимает 1 байт, а не 4, хотя логика подсказывает, что такого не должно быть.
По сути, это и не важно! Важно, какое будет смещение в структуре CERT_EXTENSION у следующего за полем BOOL fCritical поля CRYPT_OBJID_BLOB Value?
Будет ли это от начала структуры 6-й байт или 9-й? Ведь от этого зависит корректность передачи параметров в функцию CryptFormatObject.
Пока делаю вот так:

...
* Получим значение rgExtension от CryptoAPI-функции CertFindExtension
lcOID_CRL_REASON_CODE = szOID_CRL_REASON_CODE && "2.5.29.21"
CRLEntry_cExtension = CTOBIN(SubStr(laCRLEntry[lI], 17, 4), "4RS") && Number of elements in the rgExtension member array of extensions
CRLEntry_rgExtension = CTOBIN(SubStr(laCRLEntry[lI], 21, 4), "4RS") && Array of pointers to CERT_EXTENSION structures, each providing information about the revoked certificate
rgExtension = CertFindExtension(@lcOID_CRL_REASON_CODE, CRLEntry_cExtension, CRLEntry_rgExtension) && szOID_CRL_REASON_CODE = "2.5.29.21"
If rgExtension > 0
* Получим из rgExtension структуру CERT_EXTENSION
lcCERT_EXTENSION = SYS(2600, rgExtension, 13) && Структура CERT_EXTENSION, размером 13 байт или 16 байт?
* Не будем получать содержимое BLOB-объекта с выделением памяти
* по совету Игоря Королёва: forum.foxclub.ru
* В первых 4 из 8 байтах BLOB-объекта хранится размер поля
cbValue = SubStr(m.lcCERT_EXTENSION, 6, 4) && CRLExtension.Value.cbData
* В последних 4 из 8 байтах BLOB-объекта хранится значение поля
pbValue = SubStr(m.lcCERT_EXTENSION, 10, 4) && CRLExtension.Value.pbData
* То есть BLOB это: cbValue + pbValue (size, in bytes + pointer to a buffer)
dwCertEncodingType = X509_ASN_ENCODING && 0x00000001
dwFormatType = 0
dwFormatStrType = 0
pFormatStruct = 0
lpszStructType = szOID_CRL_REASON_CODE && "2.5.29.21"
pbEncoded = pbValue
cbEncoded = cbValue
pbFormat = NULL
cbFormat = 0
bResult = CryptFormatObject(dwCertEncodingType, dwFormatType, dwFormatStrType, @pFormatStruct, @lpszStructType, @pbEncoded, cbEncoded, @pbFormat, @cbFormat)
If bResult > 0
pbFormat = REPLICATE(CHR(0), m.cbFormat)
bResult = CryptFormatObject(dwCertEncodingType, dwFormatType, dwFormatStrType, @pFormatStruct, @lpszStructType, @pbEncoded, cbEncoded, @pbFormat, @cbFormat)
strCRLReasonCode = AllT(pbFormat)
=MessageBox("pbFormat = "+strCRLReasonCode, 64, "Сообщение")
Else
=MessageBox("CryptFormatObject вернул 0!", 16, "Ошибка")
EndIf
EndIf

В итоге, данный код даже не доходит до вывода сообщения "CryptFormatObject вернул 0".
Всё наглухо умирает на первом вызове функции CryptFormatObject.
Так тоже не работает:
cbValue = CTOBIN(SubStr(m.lcCERT_EXTENSION, 6, 4), "4RS") && CRLExtension.Value.cbData
pbValue = CTOBIN(SubStr(m.lcCERT_EXTENSION, 10, 4), "4RS") && CRLExtension.Value.pbData
Где в приведенном коде ошибка? Возможно, из-за бессонной ночи наступило помутнение разума?
Но вообще, это адский C++ interop, который трудно понять, не зная, как в C++ работают указатели, структуры и C-подобные массивы и как работает маршалон в interop.



Исправлено 1 раз(а). Последнее : rvc44, 02.09.19 13:16
Ratings: 0 negative/0 positive
Re: Найти CRls
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
of63
Способ то давай, создать фоксовое Integer-число (чтобы его передать функции? зачем все это нужно?! параметры в АПИ все равно передаютмя как байты, можно передать любое значение сташего байта, и для этого не оьязателдьно использовать BINNOC и наоборотный его аналоu. Да, неудачный получился BINTOC

Дело в другом.
В Фоксе нет аналогов типов данных, и для каждого типа нужно писать свою обертку, если в этом есть смысл.
Типов немало, они в фоксе не систематизированы, и в каждом случае результат добивается героической борьбой.
Обычно эта проблема вскрывается при работе со структурами.
ИК в каждом случае для конкретного типа в скрытой форме дает эти преобразования, и на этом строит свои теории.
Ratings: 0 negative/0 positive
Re: Найти CRls
rvc44

Сообщений: 2211
Откуда: Тамбов
Дата регистрации: 06.12.2005
Кстати, помимо VFP, все эти знания как вручную работать с API и со структурами данных, могут пригодиться и на Python'е, где вместо CreateObject можно использовать Dispatch и вперёд!
Вот здесь есть пример: www.mpss-pdx.com

# Python as a Way Forward for VFP Developers
# Файл pwtest.py (Copyright 2018, James Heuer, page 24 of 54)
# A single call to the Dispatch() function works exactly like CREATEOBJECT() in VFP when accessing a COM ProgID (like “Excel.Application”).
from __future__ import print_function
from win32com.client import Dispatch
from pythoncom import com_error
from MPSSCommon import MPSSBaseTools as mTools
try:
oHEX = Dispatch('swfoxdemo.makehexstring')
except com_Error:
print("Dispatch failed. Did you forget to register the DLL?")
oHEX = None
except:
print("Unidentified error occured.")
oHEX = None
if oHex is not None:
cSourceString = "TESTING 12345"
cHexVersion = oHEX.strtohex(cSourceString)
print(("Source '%s' Converted to HEX: '%s'\n" % (cSourceString, cHexVersion)))
cTestString = oHEX.hextostr(cHexVersion)
print("HEX string '%s' Restored to String: '%s'\n" % (cHexVersion, cTestString))
xArray = oHEX.gettestarray() # demo function in the VFP COM object, returns a "tuple"
print("ARRAY", xArray)
print("")
tCorrectedTime = mTools.PyTime2datetime(xArray[1])
print("Corrected DateTime", tCorrectedTime)
del oHex
# Для генерации нового уникального GUID
import pythoncom
pythoncom.CreateGuid()
IID('{1879101E-4A32-4922-86E5-43E2B8D0F50E}')
# На стр.35 работа с DBF
# На стр.38 пример создания DBF-файла через Python CodeBase Tools
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 25 (Гостей: 25)

© 2000-2024 Fox Club 
Яндекс.Метрика