Error invalid user buffer

Функция SendARP (iphlpapi.h) Функция SendARP отправляет запрос протокола ARP для получения физического адреса, соответствующего указанному целевому IPv4-адресу. Синтаксис Параметры Целевой IPv4-адрес в виде структуры IPAddr . Запрос ARP пытается получить физический адрес, соответствующий этому IPv4-адресу. Исходный IPv4-адрес отправителя в виде структуры IPAddr . Этот параметр является необязательным и используется для выбора интерфейса для отправки […]

Содержание

  1. Функция SendARP (iphlpapi.h)
  2. Синтаксис
  3. Параметры
  4. Возвращаемое значение
  5. Комментарии
  6. Примеры
  7. System Error Codes (1700-3999)

Функция SendARP (iphlpapi.h)

Функция SendARP отправляет запрос протокола ARP для получения физического адреса, соответствующего указанному целевому IPv4-адресу.

Синтаксис

Параметры

Целевой IPv4-адрес в виде структуры IPAddr . Запрос ARP пытается получить физический адрес, соответствующий этому IPv4-адресу.

Исходный IPv4-адрес отправителя в виде структуры IPAddr . Этот параметр является необязательным и используется для выбора интерфейса для отправки запроса на запись ARP. Вызывающий объект может указать ноль, соответствующий INADDR_ANY IPv4-адресу для этого параметра.

Указатель на массив переменных ULONG . Этот массив должен содержать по крайней мере два элемента ULONG для хранения физического адреса Ethernet или кольца маркеров. Первые шесть байтов этого массива получают физический адрес, соответствующий IPv4-адресу, указанному параметром DestIP .

[in, out] PhyAddrLen

При входе указатель на значение ULONG , указывающее максимальный размер буфера в байтах, приложение отложило на получение физического адреса или MAC-адреса. Размер буфера должен быть не менее 6 байт для физического адреса Ethernet или кольца маркеров.

Буфер для получения физического адреса указывает на параметр pMacAddr .

При успешном выходе этот параметр указывает на значение, указывающее количество байтов, записанных в буфер, на который указывает pMacAddr.

Возвращаемое значение

Если функция завершается успешно, возвращаемое значение NO_ERROR.

Если функция завершается ошибкой, возвращаемое значение является одним из следующих кодов ошибок.

Код возврата Описание
ERROR_BAD_NET_NAME Не найдено сетевое имя». Эта ошибка возвращается в Windows Vista и более поздних версиях, когда ответ ARP на запрос SendARP не получен. Эта ошибка возникает, если не удалось достичь адреса IPv4 назначения, так как он находится не в той же подсети или на конечном компьютере не работает.
ERROR_BUFFER_OVERFLOW Имя файла слишком длинное. Эта ошибка возвращается в Windows Vista, если значение ULONG , указываемое параметром PhyAddrLen , меньше 6, то размер, необходимый для хранения полного физического адреса.
ERROR_GEN_FAILURE Устройство, подключенное к системе, не работает. Эта ошибка возвращается в Windows Server 2003 и более ранних версиях, когда ответ ARP на запрос SendARP не был получен. Эта ошибка может возникнуть, если не удалось связаться с адресом IPv4 назначения, так как он находится не в той же подсети или на конечном компьютере не работает.
ERROR_INVALID_PARAMETER Один из параметров недопустим. Эта ошибка возвращается в Windows Server 2003 и более ранних версиях, если параметр pMacAddr или PhyAddrLen является указателем NULL .
ERROR_INVALID_USER_BUFFER Предоставленный пользовательский буфер недопустим для запрошенной операции. Эта ошибка возвращается в Windows Server 2003 и более ранних версиях, если значение ULONG , на которое указывает параметр PhyAddrLen , равно нулю.
ERROR_NOT_FOUND Элемент не найден. Эта ошибка возвращается в Windows Vista, если параметр SrcIp не указывает исходный IPv4-адрес на интерфейсе на локальном компьютере или IP-адрес INADDR_ANY (IPv4-адрес 0.0.0.0.0).
ERROR_NOT_SUPPORTED Функция SendARP не поддерживается операционной системой, работающей на локальном компьютере.
Другое Если функция завершается ошибкой, используйте FormatMessage , чтобы получить строку сообщения для возвращенной ошибки.

Комментарии

Функция SendARP используется для запроса физического аппаратного адреса (иногда называемого MAC-адресом), который соответствует указанному IPv4-адресу назначения. Если запрошенная информация отсутствует в таблице ARP на локальном компьютере, функция SendARP вызовет отправку запроса ARP для получения физического адреса. Если функция выполнена успешно, физический адрес, соответствующий указанному целевому IPv4-адресу, возвращается в массиве, на который указывает параметр pMacAddr .

Физический адрес IPv4-адреса доступен только в том случае, если целевой IPv4-адрес находится в локальной подсети (IPv4-адрес можно получить напрямую без прохождения маршрутизаторов). Функция SendARP завершится ошибкой, если целевой IPv4-адрес не находится в локальной подсети.

Если функция SendARP успешно работает в Windows Vista и более поздних версиях, таблица ARP на локальном компьютере обновляется с результатами. Если функция SendARP успешно работает в Windows Server 2003 и более ранних версиях, таблица ARP на локальном компьютере не затрагивается.

Функция SendARP в Windows Vista и более поздних версиях возвращает разные возвращаемые значения ошибок, отличные от функции SendARP в Windows Server 2003 и более ранних версиях.

В Windows Vista и более поздних версиях указатель NULL , переданный в качестве параметра pMacAddr или PhyAddrLen в функцию SendARP , приводит к нарушению доступа, и приложение завершается. Если ошибка возникает в Windows Vista и более поздних версиях, а ERROR_BAD_NET_NAME, ERROR_BUFFER_OVERFLOW или ERROR_NOT_FOUND возвращается, значение ULONG , указываемое параметром PhyAddrLen , равно нулю. Если значение ULONG , указываемое параметром PhyAddrLen , меньше 6 в Windows Vista и более поздних версиях, функция SendARP возвращает ERROR_BUFFER_OVERFLOW указывая, что буфер для получения физического адреса слишком мал. Если параметр SrcIp указывает IPv4-адрес, который не является интерфейсом на локальном компьютере, функция SendARP в Windows Vista и более поздних версий возвращает ERROR_NOT_FOUND.

В Windows Server 2003 и более ранних версиях указатель NULL, переданный в качестве параметра pMacAddr или PhyAddrLen в функцию SendARP, возвращает ERROR_INVALID_PARAMETER. Если ошибка возникает в Windows Server 2003 и более ранних версиях и возвращается ERROR_GEN_FAILURE или ERROR_INVALID_USER_BUFFER , значение ULONG , указываемое параметром PhyAddrLen , равное нулю. Если значение ULONG , на которое указывает параметр PhyAddrLen , меньше 6 в Windows Server 2003 и более ранних версиях, функция SendARP не возвращает ошибку, но возвращает только часть аппаратного адреса в массиве, на который указывает параметр pMacAddr . Таким образом, если значение, на которое указывает параметр PhyAddrLen , равно 4, то в массиве, на который указывает параметр pMacAddr , возвращаются только первые 4 байта аппаратного адреса. Если параметр SrcIp указывает IPv4-адрес, который не является интерфейсом на локальном компьютере, функция SendARP в Windows Server 2003 и более ранних версиях игнорирует параметр SrcIp и использует IPv4-адрес на локальном компьютере для исходного IPv4-адреса.

Функция GetIpNetTable извлекает таблицу ARP на локальном компьютере, который сопоставляет IPv4-адреса с физическими адресами.

Функция CreateIpNetEntry создает запись ARP в таблице ARP на локальном компьютере.

Функция DeleteIpNetEntry удаляет запись ARP из таблицы ARP на локальном компьютере.

Функция SetIpNetEntry изменяет существующую запись ARP в таблице ARP на локальном компьютере.

Функция FlushIpNetTable удаляет все записи ARP для указанного интерфейса из таблицы ARP на локальном компьютере.

В Windows Vista и более поздних версиях функция ResolveIpNetEntry2 может использоваться для замены функции SendARP . Запрос ARP отправляется, если элемент адресаMIB_IPNET_ROW2 структуры , переданной функции ResolveIpNetEntry2 , является IPv4-адресом.

В Windows Vista новую группу функций можно использовать для доступа, изменения и удаления записей таблицы ARP, когда элемент адреса структуры MIB_IPNET_ROW2 , передаваемой этим функциям, является IPv4-адресом. Новые функции включают следующие функции: GetIpNetTable2, CreateIpNetEntry2, DeleteIpNetEntry2, FlushIpNetTable2 и SetIpNetEntry2.

Сведения о типе данных IPAddr см. в разделе «Типы данных Windows». Чтобы преобразовать IP-адрес между точечной десятичной нотацией и форматом IPAddr , используйте функции inet_addr и inet_ntoa .

Примеры

В следующем коде показано, как получить аппаратный или MAC-адрес, связанный с указанным IPv4-адресом.

Источник

System Error Codes (1700-3999)

This information is intended for developers debugging system errors. For other errors, such as issues with Windows Update, there is a list of resources on the Error codes page.

The following list describes system error codes for errors 1700 to 3999. They are returned by the GetLastError function when many functions fail. To retrieve the description text for the error in your application, use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag.

RPC_S_INVALID_STRING_BINDING

The string binding is invalid.

RPC_S_WRONG_KIND_OF_BINDING

The binding handle is not the correct type.

RPC_S_INVALID_BINDING

The binding handle is invalid.

RPC_S_PROTSEQ_NOT_SUPPORTED

The RPC protocol sequence is not supported.

RPC_S_INVALID_RPC_PROTSEQ

The RPC protocol sequence is invalid.

RPC_S_INVALID_STRING_UUID

The string universal unique identifier (UUID) is invalid.

RPC_S_INVALID_ENDPOINT_FORMAT

The endpoint format is invalid.

RPC_S_INVALID_NET_ADDR

The network address is invalid.

RPC_S_NO_ENDPOINT_FOUND

No endpoint was found.

RPC_S_INVALID_TIMEOUT

The timeout value is invalid.

RPC_S_OBJECT_NOT_FOUND

The object universal unique identifier (UUID) was not found.

RPC_S_ALREADY_REGISTERED

The object universal unique identifier (UUID) has already been registered.

RPC_S_TYPE_ALREADY_REGISTERED

The type universal unique identifier (UUID) has already been registered.

RPC_S_ALREADY_LISTENING

The RPC server is already listening.

RPC_S_NO_PROTSEQS_REGISTERED

No protocol sequences have been registered.

RPC_S_NOT_LISTENING

The RPC server is not listening.

RPC_S_UNKNOWN_MGR_TYPE

The manager type is unknown.

RPC_S_UNKNOWN_IF

The interface is unknown.

RPC_S_NO_BINDINGS

There are no bindings.

RPC_S_NO_PROTSEQS

There are no protocol sequences.

RPC_S_CANT_CREATE_ENDPOINT

The endpoint cannot be created.

RPC_S_OUT_OF_RESOURCES

Not enough resources are available to complete this operation.

RPC_S_SERVER_UNAVAILABLE

The RPC server is unavailable.

RPC_S_SERVER_TOO_BUSY

The RPC server is too busy to complete this operation.

RPC_S_INVALID_NETWORK_OPTIONS

The network options are invalid.

RPC_S_NO_CALL_ACTIVE

There are no remote procedure calls active on this thread.

RPC_S_CALL_FAILED

The remote procedure call failed.

RPC_S_CALL_FAILED_DNE

The remote procedure call failed and did not execute.

RPC_S_PROTOCOL_ERROR

A remote procedure call (RPC) protocol error occurred.

RPC_S_PROXY_ACCESS_DENIED

Access to the HTTP proxy is denied.

RPC_S_UNSUPPORTED_TRANS_SYN

The transfer syntax is not supported by the RPC server.

RPC_S_UNSUPPORTED_TYPE

The universal unique identifier (UUID) type is not supported.

RPC_S_INVALID_TAG

The tag is invalid.

RPC_S_INVALID_BOUND

The array bounds are invalid.

RPC_S_NO_ENTRY_NAME

The binding does not contain an entry name.

RPC_S_INVALID_NAME_SYNTAX

The name syntax is invalid.

RPC_S_UNSUPPORTED_NAME_SYNTAX

The name syntax is not supported.

RPC_S_UUID_NO_ADDRESS

No network address is available to use to construct a universal unique identifier (UUID).

RPC_S_DUPLICATE_ENDPOINT

The endpoint is a duplicate.

RPC_S_UNKNOWN_AUTHN_TYPE

The authentication type is unknown.

RPC_S_MAX_CALLS_TOO_SMALL

The maximum number of calls is too small.

RPC_S_STRING_TOO_LONG

The string is too long.

RPC_S_PROTSEQ_NOT_FOUND

The RPC protocol sequence was not found.

RPC_S_PROCNUM_OUT_OF_RANGE

The procedure number is out of range.

RPC_S_BINDING_HAS_NO_AUTH

The binding does not contain any authentication information.

RPC_S_UNKNOWN_AUTHN_SERVICE

The authentication service is unknown.

RPC_S_UNKNOWN_AUTHN_LEVEL

The authentication level is unknown.

RPC_S_INVALID_AUTH_IDENTITY

The security context is invalid.

RPC_S_UNKNOWN_AUTHZ_SERVICE

The authorization service is unknown.

EPT_S_INVALID_ENTRY

The entry is invalid.

EPT_S_CANT_PERFORM_OP

The server endpoint cannot perform the operation.

EPT_S_NOT_REGISTERED

There are no more endpoints available from the endpoint mapper.

RPC_S_NOTHING_TO_EXPORT

No interfaces have been exported.

RPC_S_INCOMPLETE_NAME

The entry name is incomplete.

RPC_S_INVALID_VERS_OPTION

The version option is invalid.

RPC_S_NO_MORE_MEMBERS

There are no more members.

RPC_S_NOT_ALL_OBJS_UNEXPORTED

There is nothing to unexport.

RPC_S_INTERFACE_NOT_FOUND

The interface was not found.

RPC_S_ENTRY_ALREADY_EXISTS

The entry already exists.

RPC_S_ENTRY_NOT_FOUND

The entry is not found.

RPC_S_NAME_SERVICE_UNAVAILABLE

The name service is unavailable.

RPC_S_INVALID_NAF_ID

The network address family is invalid.

RPC_S_CANNOT_SUPPORT

The requested operation is not supported.

RPC_S_NO_CONTEXT_AVAILABLE

No security context is available to allow impersonation.

RPC_S_INTERNAL_ERROR

An internal error occurred in a remote procedure call (RPC).

RPC_S_ZERO_DIVIDE

The RPC server attempted an integer division by zero.

RPC_S_ADDRESS_ERROR

An addressing error occurred in the RPC server.

RPC_S_FP_DIV_ZERO

A floating-point operation at the RPC server caused a division by zero.

RPC_S_FP_UNDERFLOW

A floating-point underflow occurred at the RPC server.

RPC_S_FP_OVERFLOW

A floating-point overflow occurred at the RPC server.

RPC_X_NO_MORE_ENTRIES

The list of RPC servers available for the binding of auto handles has been exhausted.

RPC_X_SS_CHAR_TRANS_OPEN_FAIL

Unable to open the character translation table file.

RPC_X_SS_CHAR_TRANS_SHORT_FILE

The file containing the character translation table has fewer than 512 bytes.

RPC_X_SS_IN_NULL_CONTEXT

A null context handle was passed from the client to the host during a remote procedure call.

RPC_X_SS_CONTEXT_DAMAGED

The context handle changed during a remote procedure call.

RPC_X_SS_HANDLES_MISMATCH

The binding handles passed to a remote procedure call do not match.

RPC_X_SS_CANNOT_GET_CALL_HANDLE

The stub is unable to get the remote procedure call handle.

RPC_X_NULL_REF_POINTER

A null reference pointer was passed to the stub.

RPC_X_ENUM_VALUE_OUT_OF_RANGE

The enumeration value is out of range.

RPC_X_BYTE_COUNT_TOO_SMALL

The byte count is too small.

RPC_X_BAD_STUB_DATA

The stub received bad data.

ERROR_INVALID_USER_BUFFER

The supplied user buffer is not valid for the requested operation.

ERROR_UNRECOGNIZED_MEDIA

The disk media is not recognized. It may not be formatted.

ERROR_NO_TRUST_LSA_SECRET

The workstation does not have a trust secret.

ERROR_NO_TRUST_SAM_ACCOUNT

The security database on the server does not have a computer account for this workstation trust relationship.

ERROR_TRUSTED_DOMAIN_FAILURE

The trust relationship between the primary domain and the trusted domain failed.

ERROR_TRUSTED_RELATIONSHIP_FAILURE

The trust relationship between this workstation and the primary domain failed.

ERROR_TRUST_FAILURE

The network logon failed.

RPC_S_CALL_IN_PROGRESS

A remote procedure call is already in progress for this thread.

ERROR_NETLOGON_NOT_STARTED

An attempt was made to logon, but the network logon service was not started.

ERROR_ACCOUNT_EXPIRED

The user’s account has expired.

ERROR_REDIRECTOR_HAS_OPEN_HANDLES

The redirector is in use and cannot be unloaded.

ERROR_PRINTER_DRIVER_ALREADY_INSTALLED

The specified printer driver is already installed.

ERROR_UNKNOWN_PORT

The specified port is unknown.

ERROR_UNKNOWN_PRINTER_DRIVER

The printer driver is unknown.

ERROR_UNKNOWN_PRINTPROCESSOR

The print processor is unknown.

ERROR_INVALID_SEPARATOR_FILE

The specified separator file is invalid.

ERROR_INVALID_PRIORITY

The specified priority is invalid.

ERROR_INVALID_PRINTER_NAME

The printer name is invalid.

ERROR_PRINTER_ALREADY_EXISTS

The printer already exists.

ERROR_INVALID_PRINTER_COMMAND

The printer command is invalid.

ERROR_INVALID_DATATYPE

The specified datatype is invalid.

ERROR_INVALID_ENVIRONMENT

The environment specified is invalid.

RPC_S_NO_MORE_BINDINGS

There are no more bindings.

ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT

The account used is an interdomain trust account. Use your global user account or local user account to access this server.

ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT

The account used is a computer account. Use your global user account or local user account to access this server.

ERROR_NOLOGON_SERVER_TRUST_ACCOUNT

The account used is a server trust account. Use your global user account or local user account to access this server.

ERROR_DOMAIN_TRUST_INCONSISTENT

The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.

ERROR_SERVER_HAS_OPEN_HANDLES

The server is in use and cannot be unloaded.

ERROR_RESOURCE_DATA_NOT_FOUND

The specified image file did not contain a resource section.

ERROR_RESOURCE_TYPE_NOT_FOUND

The specified resource type cannot be found in the image file.

ERROR_RESOURCE_NAME_NOT_FOUND

The specified resource name cannot be found in the image file.

ERROR_RESOURCE_LANG_NOT_FOUND

The specified resource language ID cannot be found in the image file.

ERROR_NOT_ENOUGH_QUOTA

Not enough quota is available to process this command.

RPC_S_NO_INTERFACES

No interfaces have been registered.

RPC_S_CALL_CANCELLED

The remote procedure call was cancelled.

RPC_S_BINDING_INCOMPLETE

The binding handle does not contain all required information.

RPC_S_COMM_FAILURE

A communications failure occurred during a remote procedure call.

RPC_S_UNSUPPORTED_AUTHN_LEVEL

The requested authentication level is not supported.

RPC_S_NO_PRINC_NAME

No principal name registered.

RPC_S_NOT_RPC_ERROR

The error specified is not a valid Windows RPC error code.

RPC_S_UUID_LOCAL_ONLY

A UUID that is valid only on this computer has been allocated.

RPC_S_SEC_PKG_ERROR

A security package specific error occurred.

RPC_S_NOT_CANCELLED

Thread is not canceled.

RPC_X_INVALID_ES_ACTION

Invalid operation on the encoding/decoding handle.

RPC_X_WRONG_ES_VERSION

Incompatible version of the serializing package.

RPC_X_WRONG_STUB_VERSION

Incompatible version of the RPC stub.

RPC_X_INVALID_PIPE_OBJECT

The RPC pipe object is invalid or corrupted.

RPC_X_WRONG_PIPE_ORDER

An invalid operation was attempted on an RPC pipe object.

RPC_X_WRONG_PIPE_VERSION

Unsupported RPC pipe version.

RPC_S_COOKIE_AUTH_FAILED

HTTP proxy server rejected the connection because the cookie authentication failed.

RPC_S_GROUP_MEMBER_NOT_FOUND

The group member was not found.

EPT_S_CANT_CREATE

The endpoint mapper database entry could not be created.

RPC_S_INVALID_OBJECT

The object universal unique identifier (UUID) is the nil UUID.

ERROR_INVALID_TIME

The specified time is invalid.

ERROR_INVALID_FORM_NAME

The specified form name is invalid.

ERROR_INVALID_FORM_SIZE

The specified form size is invalid.

ERROR_ALREADY_WAITING

The specified printer handle is already being waited on.

ERROR_PRINTER_DELETED

The specified printer has been deleted.

ERROR_INVALID_PRINTER_STATE

The state of the printer is invalid.

ERROR_PASSWORD_MUST_CHANGE

The user’s password must be changed before signing in.

ERROR_DOMAIN_CONTROLLER_NOT_FOUND

Could not find the domain controller for this domain.

ERROR_ACCOUNT_LOCKED_OUT

The referenced account is currently locked out and may not be logged on to.

OR_INVALID_OXID

The object exporter specified was not found.

OR_INVALID_OID

The object specified was not found.

OR_INVALID_SET

The object resolver set specified was not found.

RPC_S_SEND_INCOMPLETE

Some data remains to be sent in the request buffer.

RPC_S_INVALID_ASYNC_HANDLE

Invalid asynchronous remote procedure call handle.

RPC_S_INVALID_ASYNC_CALL

Invalid asynchronous RPC call handle for this operation.

RPC_X_PIPE_CLOSED

The RPC pipe object has already been closed.

RPC_X_PIPE_DISCIPLINE_ERROR

The RPC call completed before all pipes were processed.

RPC_X_PIPE_EMPTY

No more data is available from the RPC pipe.

ERROR_NO_SITENAME

No site name is available for this machine.

ERROR_CANT_ACCESS_FILE

The file cannot be accessed by the system.

ERROR_CANT_RESOLVE_FILENAME

The name of the file cannot be resolved by the system.

RPC_S_ENTRY_TYPE_MISMATCH

The entry is not of the expected type.

RPC_S_NOT_ALL_OBJS_EXPORTED

Not all object UUIDs could be exported to the specified entry.

RPC_S_INTERFACE_NOT_EXPORTED

Interface could not be exported to the specified entry.

RPC_S_PROFILE_NOT_ADDED

The specified profile entry could not be added.

RPC_S_PRF_ELT_NOT_ADDED

The specified profile element could not be added.

RPC_S_PRF_ELT_NOT_REMOVED

The specified profile element could not be removed.

RPC_S_GRP_ELT_NOT_ADDED

The group element could not be added.

RPC_S_GRP_ELT_NOT_REMOVED

The group element could not be removed.

ERROR_KM_DRIVER_BLOCKED

The printer driver is not compatible with a policy enabled on your computer that blocks NT 4.0 drivers.

ERROR_CONTEXT_EXPIRED

The context has expired and can no longer be used.

ERROR_PER_USER_TRUST_QUOTA_EXCEEDED

The current user’s delegated trust creation quota has been exceeded.

ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED

The total delegated trust creation quota has been exceeded.

ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED

The current user’s delegated trust deletion quota has been exceeded.

ERROR_AUTHENTICATION_FIREWALL_FAILED

The computer you are signing into is protected by an authentication firewall. The specified account is not allowed to authenticate to the computer.

ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED

Remote connections to the Print Spooler are blocked by a policy set on your machine.

ERROR_NTLM_BLOCKED

Authentication failed because NTLM authentication has been disabled.

ERROR_PASSWORD_CHANGE_REQUIRED

Logon Failure: EAS policy requires that the user change their password before this operation can be performed.

ERROR_INVALID_PIXEL_FORMAT

The pixel format is invalid.

ERROR_BAD_DRIVER

The specified driver is invalid.

ERROR_INVALID_WINDOW_STYLE

The window style or class attribute is invalid for this operation.

ERROR_METAFILE_NOT_SUPPORTED

The requested metafile operation is not supported.

ERROR_TRANSFORM_NOT_SUPPORTED

The requested transformation operation is not supported.

ERROR_CLIPPING_NOT_SUPPORTED

The requested clipping operation is not supported.

ERROR_INVALID_CMM

The specified color management module is invalid.

ERROR_INVALID_PROFILE

The specified color profile is invalid.

ERROR_TAG_NOT_FOUND

The specified tag was not found.

ERROR_TAG_NOT_PRESENT

A required tag is not present.

ERROR_DUPLICATE_TAG

The specified tag is already present.

ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE

The specified color profile is not associated with the specified device.

ERROR_PROFILE_NOT_FOUND

The specified color profile was not found.

ERROR_INVALID_COLORSPACE

The specified color space is invalid.

ERROR_ICM_NOT_ENABLED

Image Color Management is not enabled.

ERROR_DELETING_ICM_XFORM

There was an error while deleting the color transform.

ERROR_INVALID_TRANSFORM

The specified color transform is invalid.

ERROR_COLORSPACE_MISMATCH

The specified transform does not match the bitmap’s color space.

ERROR_INVALID_COLORINDEX

The specified named color index is not present in the profile.

ERROR_PROFILE_DOES_NOT_MATCH_DEVICE

The specified profile is intended for a device of a different type than the specified device.

ERROR_CONNECTED_OTHER_PASSWORD

The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified.

ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT

The network connection was made successfully using default credentials.

ERROR_BAD_USERNAME

The specified username is invalid.

ERROR_NOT_CONNECTED

This network connection does not exist.

ERROR_OPEN_FILES

This network connection has files open or requests pending.

ERROR_ACTIVE_CONNECTIONS

Active connections still exist.

ERROR_DEVICE_IN_USE

The device is in use by an active process and cannot be disconnected.

ERROR_UNKNOWN_PRINT_MONITOR

The specified print monitor is unknown.

ERROR_PRINTER_DRIVER_IN_USE

The specified printer driver is currently in use.

ERROR_SPOOL_FILE_NOT_FOUND

The spool file was not found.

ERROR_SPL_NO_STARTDOC

A StartDocPrinter call was not issued.

ERROR_SPL_NO_ADDJOB

An AddJob call was not issued.

ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED

The specified print processor has already been installed.

ERROR_PRINT_MONITOR_ALREADY_INSTALLED

The specified print monitor has already been installed.

ERROR_INVALID_PRINT_MONITOR

The specified print monitor does not have the required functions.

ERROR_PRINT_MONITOR_IN_USE

The specified print monitor is currently in use.

ERROR_PRINTER_HAS_JOBS_QUEUED

The requested operation is not allowed when there are jobs queued to the printer.

ERROR_SUCCESS_REBOOT_REQUIRED

The requested operation is successful. Changes will not be effective until the system is rebooted.

ERROR_SUCCESS_RESTART_REQUIRED

The requested operation is successful. Changes will not be effective until the service is restarted.

ERROR_PRINTER_NOT_FOUND

No printers were found.

ERROR_PRINTER_DRIVER_WARNED

The printer driver is known to be unreliable.

ERROR_PRINTER_DRIVER_BLOCKED

The printer driver is known to harm the system.

ERROR_PRINTER_DRIVER_PACKAGE_IN_USE

The specified printer driver package is currently in use.

ERROR_CORE_DRIVER_PACKAGE_NOT_FOUND

Unable to find a core driver package that is required by the printer driver package.

ERROR_FAIL_REBOOT_REQUIRED

The requested operation failed. A system reboot is required to roll back changes made.

ERROR_FAIL_REBOOT_INITIATED

The requested operation failed. A system reboot has been initiated to roll back changes made.

ERROR_PRINTER_DRIVER_DOWNLOAD_NEEDED

The specified printer driver was not found on the system and needs to be downloaded.

ERROR_PRINT_JOB_RESTART_REQUIRED

The requested print job has failed to print. A print system update requires the job to be resubmitted.

ERROR_INVALID_PRINTER_DRIVER_MANIFEST

The printer driver does not contain a valid manifest, or contains too many manifests.

ERROR_PRINTER_NOT_SHAREABLE

The specified printer cannot be shared.

ERROR_REQUEST_PAUSED

The operation was paused.

ERROR_IO_REISSUE_AS_CACHED

Reissue the given operation as a cached IO operation.

Источник

I am creating a program to populate a disk with a dummy file system.

Currently, I am writing files of variable sizes using WriteFile.

        WriteFile(hFile, FileData, i * 1024, &dwWrote, NULL);
        err = GetLastError();

err returns #1784 which translates to

The supplied user buffer is not valid for the requested operation. ERROR_INVALID_USER_BUFFER

So for the first 24 files, the write operation works. For file #25 on, the write operation fails.
The files are still created but the WriteFile function does not populate the files.

Any ideas on how to get past ERROR_INVALID_USER_BUFFER?

Every reference I can find to the error is limited to crashing programs and I cannot figure out how it relates to the issue I am experiencing.

EDIT:

FileData = (char *) malloc(sizeof(char) * (size_t)k * 1024);
memset(FileData, 245, sizeof(char) * (size_t)k * 1024);

FileData is set and allocated to the size of the maximum anticipate buffer.
i is the loop variable that iterates until it increments to the Maximum Size (k).

Hello,

 I’m trying to get informations about an USB device inserted into my system.
My application works in C++ and I’m porting it to c#.

Everytime, the call to SetupDiOpenDeviceInterface fails with ERROR_INVALID_USER_BUFFER.
The doc says that it does not matter when info is filled. But this is not my case.
I’m now running out of ideas please help.

I first call RegisterDeviceNotification to get notified when an USB device is inserted.
       public bool DoRegisterDeviceInterface(IntPtr mHandle,Guid InterfaceClassGuid)
        {
            DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = new DEV_BROADCAST_DEVICEINTERFACE();
            NotificationFilter.dbcc_size = Marshal.SizeOf(NotificationFilter);
            NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
            NotificationFilter.dbcc_classguid = InterfaceClassGuid;

            IntPtr buffer = Marshal.AllocHGlobal(NotificationFilter.dbcc_size);
            Marshal.StructureToPtr(NotificationFilter, buffer, true);

                        mDeviceNotifyHandle = RegisterDeviceNotification(mHandle, buffer, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
            return true;
        }

I’m correctly notified when it fires:
      protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_DEVICECHANGE:
                    // The WParam value identifies what is occurring.
                    // n = (int)m.WParam;
                    switch (m.WParam.ToInt32())
                    {
                        case DBT_DEVICEARRIVAL:
                        case DBT_DEVICEREMOVECOMPLETE:
                            DEV_BROADCAST_DEVICEINTERFACE dvi = (DEV_BROADCAST_DEVICEINTERFACE)m.GetLParam(typeof(DEV_BROADCAST_DEVICEINTERFACE));
                            DoGetDeviceDetails(dvi);
                            break;
                    }
                    break;
                case WM_QUIT:
                    device.DoUnRegisterDeviceInterface();
                    break;
            }
            base.WndProc(ref m);
        }

      private void DoGetDeviceDetails(DEV_BROADCAST_DEVICEINTERFACE dvi)
        {
           if (device == null)
            {
                device = new DeviceInformation();
            }

            if (!device.GetUSBDevices())  // This line sets the hDev
                return;

            SP_DEVINFO_DATA DeviceInfoData = device.SetupDiGetDeviceInterfaceDetail(dvi);
            if (DeviceInfoData != null)
            {
                if (DeviceInfoData.DevInst != 0)
                {
                    string desc, hardwareid, classguid, classdesc;
                    hardwareid = device.GetHardwareID(DeviceInfoData);
                    classdesc = device.GetClass(DeviceInfoData);
                    desc = device.GetDescription(DeviceInfoData);
                    classguid = device.GetClassGuid(DeviceInfoData);
                    AddDeviceItem(hardwareid, classdesc, desc, classguid);
                }
            }

        }

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto,Pack=4)] // Tried with or without Pack
    public class DEV_BROADCAST_DEVICEINTERFACE
    {
        public int dbcc_size;
        public int dbcc_devicetype;
        public int dbcc_reserved;
        public Guid dbcc_classguid;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 250)] // Tried different values.
        public string dbcc_name; // tchar[1]
    };

    [StructLayout(LayoutKind.Sequential)]
    public class SP_DEVINFO_DATA
    {
        public int cbSize;
        public Guid ClassGuid;
        public int DevInst;    // DEVINST handle
        public ulong Reserved;
    };

        [DllImport(«setupapi.dll», SetLastError = true)]
        public static extern Boolean
            SetupDiOpenDeviceInterfaceA(
                IntPtr DeviceInfoSet,
                IntPtr DevicePath, //

In the .h header, it’s a PCSTR
                int OpenFlags,
                ref SP_DEVINFO_DATA DeviceInterfaceData);

        [DllImport(«setupapi.dll»)]
        public static extern Boolean
            SetupDiGetDeviceInterfaceDetailA(
                IntPtr DeviceInfoSet,
                ref SP_DEVINFO_DATA DeviceInterfaceData,
                IntPtr DeviceInterfaceDetailData,
                int DeviceInterfaceDetailDataSize,
                ref int RequiredSize,
                ref SP_DEVINFO_DATA DeviceInfoData);


      private IntPtr hDev;


        public bool GetUSBDevices()
        {

            Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid(«A5DCBF10-6530-11D2-901F-00C04FB951ED»);
            hDev = SetupDiGetClassDevsA(  // hDev is correctly set
                ref GUID_DEVINTERFACE_USB_DEVICE,
                null,
                IntPtr.Zero,
                DIGCF_DEVICEINTERFACE | DIGCF_PROFILE
                );
            if (hDev.ToInt32() == -1)
                return false;

            return true;

        }

        public SP_DEVINFO_DATA SetupDiGetDeviceInterfaceDetail(DEV_BROADCAST_DEVICEINTERFACE dvi)
        {
            SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA();  // Lazy coding: Actually it’s SP_DEVICE_INTERFACE_DATA structure, but they are equivalent.
            DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData);
            DeviceInfoData.DevInst = 0;
            DeviceInfoData.ClassGuid = System.Guid.Empty;
            DeviceInfoData.Reserved = 0;

            if (!SetupDiOpenDeviceInterfaceA(
                hDev,
               // dvi.dbcc_name, // I feel that the problem is here. I tried several syntax, the value below is the content of dbcc_name.
               Marshal.StringToHGlobalAnsi(@»\?USB#VID_07AB&PID_FCCA#FW520_200000000000B703#{a5dcbf10-6530-11d2-901f-00c04fb951ed}»),
                0,
                ref DeviceInfoData))
            {
                // Get the last error and display it.
                int error = Marshal.GetLastWin32Error(); // Always fail.
              //  return (SP_DEVINFO_DATA)null;
            }

            SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA();
            dd.cbSize = Marshal.SizeOf(dd);
            int val = 0;
            if (!SetupDiGetDeviceInterfaceDetailA(
                hDev,
                ref DeviceInfoData,
                IntPtr.Zero,
                0,
                ref val,
                ref dd))
                {
                    int error = Marshal.GetLastWin32Error(); // Always fail.
                    //no such device:
                    SetupDiDestroyDeviceInfoList(hDev);
                }
            return dd;
        }


Any help would be gratly appreciated.
Thanks.

I’m starting to hate the ‘system’. I added a ‘WriteFile’ function and it’s throwing a System Error 1784: The supplied user buffer is not valid for the requested operation. ERROR_INVALID_USER_BUFFER

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//handle declarations
	HWND txtfld;
	HWND btn;
	HWND txtbx;
	HANDLE hfile;
	HWND txtbx2;
	HWND txtbx3;
	HWND txtbx4;
	HWND txtbx5;
	HWND txtbx6;
	HWND txtbx7;
	HANDLE hfile2;
//variable declarations
    std::string line;
    char* ntns=new char[8000];
    size_t srchd;
    char* dtls=new char[200];
    char txtmem[40];
    char txtmem2[40];
    char txtmem3[40];
    char txtmem4[40];
    char txtmem5[40];
    char txtmem6[40];
    char txtmem7[40];
    char* add_buf=new char[8001];
    char* ntns2=new char[8000];
	
/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {

	
	switch(Message) {
	
    case WM_CREATE:
    	{
    		txtfld = CreateWindowA("STATIC", "    CommonwealthCore Database Application", WS_VISIBLE | WS_CHILD | WS_BORDER, 150, 20, 300, 20, hwnd, NULL, NULL, NULL);
    		txtfld = CreateWindowA("STATIC", "                     Find A Nation:", WS_VISIBLE | WS_CHILD | WS_BORDER, 20, 70, 250, 20, hwnd, NULL, NULL, NULL);
    		txtbx = CreateWindowA("EDIT", "NationShortName", WS_VISIBLE | WS_CHILD | WS_BORDER, 20, 110, 250, 20, hwnd, NULL, NULL, NULL);
    		btn = CreateWindowA("BUTTON", "SEARCH", WS_VISIBLE | WS_CHILD | WS_BORDER, 100, 150, 100, 30, hwnd, (HMENU) 1, NULL, NULL);
    		txtfld = CreateWindowA("STATIC", "            Add Nation To Database:", WS_VISIBLE | WS_CHILD | WS_BORDER, 300, 70, 250, 20, hwnd, NULL, NULL, NULL);
    		txtbx2 = CreateWindowA("EDIT", "NationShortName", WS_VISIBLE | WS_CHILD | WS_BORDER, 300, 110, 250, 20, hwnd, NULL, NULL, NULL);
    		txtbx3 = CreateWindowA("EDIT", "Population (no commas)", WS_VISIBLE | WS_CHILD | WS_BORDER, 300, 150, 250, 20, hwnd, NULL, NULL, NULL);
    		txtbx4 = CreateWindowA("EDIT", "Tax Rate (do not include % sign)", WS_VISIBLE | WS_CHILD | WS_BORDER, 300, 190, 250, 20, hwnd, NULL, NULL, NULL);
    		txtbx5 = CreateWindowA("EDIT", "% Defense Spending (no % sign)", WS_VISIBLE | WS_CHILD | WS_BORDER, 300, 230, 250, 20, hwnd, NULL, NULL, NULL);
    		txtbx6 = CreateWindowA("EDIT", "Economy Points", WS_VISIBLE | WS_CHILD | WS_BORDER, 300, 270, 250, 20, hwnd, NULL, NULL, NULL);
    		txtbx7 = CreateWindowA("EDIT", "Password (case sensitive)", WS_VISIBLE | WS_CHILD | WS_BORDER, 300, 310, 250, 20, hwnd, NULL, NULL, NULL);
    		btn = CreateWindowA("BUTTON", "ADD", WS_VISIBLE | WS_CHILD | WS_BORDER, 380, 350, 100, 30, hwnd, (HMENU) 2, NULL, NULL);
    		break;
    	}

	case WM_COMMAND:
		{
		
		switch (LOWORD (wParam) )
		{
			case 1:
				{
					//search engine--------------------------
					int gwt1=0;
					char * txtmemptr = &txtmem[0];
					gwt1=GetWindowText(txtbx, &txtmem[0], 40);
					::MessageBeep(MB_ICONERROR);
					::MessageBoxA(hwnd, txtmemptr , "Searching For Nation:", MB_OK);
					hfile=CreateFile("nations.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					int x=ReadFile(hfile, (LPVOID)ntns, 8000, NULL, NULL);
					std::string ntnst=(std::string)ntns;
					srchd=ntnst.find(txtmemptr);
					//display details------------------------
					if(srchd!=std::string::npos)
					{
					::MessageBoxA(hwnd, "The above nation was found.nDetails will be displayed.", txtmemptr, MB_OK);
					dtls=(char*)ntnst.c_str();
					std::vector<char> rslts;
					for(int i=0;i<148;i++)
					{
					rslts.push_back(dtls[srchd+i]);
					}
					std::stringstream ssrslts;
					for(int j=0;j<148;j++)
					{
					ssrslts << rslts[j];
					}
					std::string strrslts=ssrslts.str();
					char * rsltst=new char[148];
					rsltst=(char*)strrslts.c_str();
					CreateWindowA("STATIC", rsltst, WS_VISIBLE | WS_CHILD | WS_BORDER, 20, 200, 250, 200, hwnd, NULL, NULL, NULL);
					}
					else
					{
						::MessageBoxA(hwnd, "The above nation was not found.", txtmemptr, MB_OK);
					}
					CancelIo(hfile);
					break;
				}
			case 2:
				{
					hfile=CreateFile("nations.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					hfile2=CreateFile("nations.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					//read/save file before re-writing-------
					int x=ReadFile(hfile, (LPVOID)ntns2, 8000, NULL, NULL);
					std::string ntns2t=(std::string)ntns2;
					CancelIo(hfile);
					//add nation to database-----------------
					int gwt2=0;
					int gwt3=0;
					int gwt4=0;
					int gwt5=0;
					int gwt6=0;
					int gwt7=0;
					char * txtmemptr2=&txtmem2[0];
					char * txtmemptr3=&txtmem3[0];
					char * txtmemptr4=&txtmem4[0];
					char * txtmemptr5=&txtmem5[0];
					char * txtmemptr6=&txtmem6[0];
					char * txtmemptr7=&txtmem7[0];
					gwt2=GetWindowText(txtbx7, &txtmem2[0], 40);
					std::string txtmem2str=txtmem2;
					if(txtmem2str != "CCPW01")
					{
						::MessageBoxA(hwnd, "Incorrect Password.nApplication Will Terminate.", "PERMISSIONS ERROR", MB_OK);
						PostQuitMessage(0);
					}
					else
					{
						::MessageBoxA(hwnd, "Password AcceptednClick 'OK' To Proceed.", "Password Accepted", MB_OK);
					}
					gwt3=GetWindowText(txtbx2, &txtmem3[0], 40);
					gwt4=GetWindowText(txtbx3, &txtmem4[0], 40);
					gwt5=GetWindowText(txtbx4, &txtmem5[0], 40);
					gwt6=GetWindowText(txtbx5, &txtmem6[0], 40);
					gwt7=GetWindowText(txtbx6, &txtmem7[0], 40);
					std::stringstream add_buf_strm;
					add_buf_strm << ntns2t << "n" << "Nation: " << txtmem3 << "n" << "Population: " << txtmem4 << "n" << "% Tax Rate: " << txtmem5 << "n" << "% Defense Spending: " << txtmem6 << "n" << "Economy Points: " << txtmem7 << "n" << "                                       ";
					std::string add_buf_pre = add_buf_strm.str();
					add_buf=(char*)add_buf_pre.c_str();
					::MessageBoxA(hwnd, (LPCSTR)add_buf, "Received Input:", MB_OK);
					DWORD num=8000;
					int rslt_of_wf = WriteFile(hfile2, (LPCVOID)add_buf, num, NULL, NULL);
					ErrorExit("Error:");
					if(rslt_of_wf !=0)
					{
						::MessageBoxA(hwnd, "Process was successful.nFile added to database.nSearch nation to confirm.", "SUCCESS", MB_OK);
					}
					else
					{
						::MessageBeep(MB_ICONERROR);
						::MessageBoxA(hwnd, "Process failed.nUnable to add file to database.", "FAILURE", MB_OK);
					}
				}
				
		}
}

I’ve tried everything. The CancelIo function, tinkering with the buffer size, etc.

I’ve spend the past 4 or so hours researching and trying things and nothing works. It seems that most people get this error because they didn’t allow enough space for the buffer. This is weird because my ReadFile functions work fine, and the ::MessageBox displays exactly what should be written to the file. (using the exact same var, just casted differently).

So is there a solution to this problem? From all of my research, i’ve found not a single article/post (not even on stackoverflow).


Функция ReadFile читает данные
из файла, начиная с позиции, обозначенной
указателем файла. После того, как операция
чтения была закончена, указатель файла
перемещается на число действительно
прочитанных байтов, если дескриптор файла
не создан с атрибутом асинхронной операции.
Если дескриптор файла создается для
асинхронного ввода — вывода, приложение
должно переместить позицию указателя файла
после операции чтения.

Эта функция предназначена и для
синхронной и асинхронной операции. Функция
ReadFileEx

предназначена исключительно для
асинхронной операции. Это дает возможность
приложению выполнять другие действия в
ходе операции чтения файла.

Синтаксис
BOOL ReadFile(
  HANDLE hFile,                // дескриптор файла
  LPVOID lpBuffer,             // буфер данных
  DWORD nNumberOfBytesToRead,  // число байтов для чтения
  LPDWORD lpNumberOfBytesRead, // число прочитанных байтов
  LPOVERLAPPED lpOverlapped    // асинхронный буфер
);

Параметры

hFile

[in] Дескриптор файла, который
читается. Дескриптор файла должен быть,
создан с правом доступа GENERIC_READ.
Подробную информацию см.  в статье
Защита
файла и права доступа
.

Windows
NT/2000/XP:
Для асинхронных операций чтения,
параметр hFile может быть любым
дескриптором открытым с флажком FILE_FLAG_OVERLAPPED
функцией CreateFile или
дескриптор сокета, возвращенный функцией socket или
accept.

Windows 95/98/Me:
Для асинхронных операций чтения, параметр hFile
может быть  коммуникационным ресурсом,
открытым с флажком FILE_FLAG_OVERLAPPED
функцией CreateFile или дескриптор сокета,
возвращенный при помощи функций socket или
accept . Вы
не можете выполнять асинхронные операции
чтения в почтовом ящике в ядре Windows,
именованных каналах или файлах на диске.

lpBuffer

[out] Указатель на буфер,
который принимает прочитанные данные из
файла.

nNumberOfBytesToRead

[in] Число байтов, которые
читаются из файла.

lpNumberOfBytesRead

[out] Указатель на переменную,
которая получает число прочитанных байтов.
Функция ReadFile устанавливает это
значение в нуль перед началом любой работы
или проверкой ошибок. Если этот параметр
равняется нулю, когда ReadFile возвращает
значение ИСТИНА (TRUE) для именованного
канала, другой конец канала в режиме
передачи сообщений вызывает функцию
WriteFile

с параметром nNumberOfBytesToWrite 
установленным в нуль.

Windows
NT/2000/XP:
Если параметр lpOverlapped имеет
значение ПУСТО (NULL), параметр lpNumberOfBytesRead
не может быть значением ПУСТО (NULL). Если lpOverlapped
имеет —  значение не ПУСТО (NULL), lpNumberOfBytesRead
может быть значением ПУСТО (NULL). Если это —
асинхронная операция чтения, Вы можете
получить число прочитанных байтов при
помощи вызова функции GetOverlappedResult.
Если параметр hFile связан с портом
завершения ввода-вывода, Вы можете получить
число прочитанных байтов при помощи вызова
функции GetQueuedCompletionStatus.

Если используются порты
завершения ввода-вывода, а Вы используете
процедуру повторного вызова, чтобы
освободить занимаемую память структурой OVERLAPPED,
на которую указывает параметр lpOverlapped, задайте  ПУСТО (NULL), как значение этого
параметра, чтобы избежать проблемы
искажения данных в памяти в ходе ее
освобождения. Эта проблема искажения
данных в памяти становится причиной
возвращения в этом параметре неверного
числа байтов .

Windows 95/98/Me: Этот
параметр не может быть ПУСТО (NULL).

lpOverlapped

[in] Указатель на структуру OVERLAPPED.
Эта структура требуется тогда, если
параметр hFile создавался с флажком FILE_FLAG_OVERLAPPED.

Если hFile был открыт
с флажком FILE_FLAG_OVERLAPPED, у
параметра lpOverlapped  не должно быть
значения ПУСТО (NULL). Он должен указать на
правильную структуру OVERLAPPED. Если hFile
создавался с флажком FILE_FLAG_OVERLAPPED,
а lpOverlapped имеет значение ПУСТО (NULL),
функция может неправильно сообщить о
завершении операций чтения.

Если hFile был открыт
с флажком FILE_FLAG_OVERLAPPED, а lpOverlapped
имеет значение не ПУСТО (NULL), операция
чтения начинается при смещении, заданном в
структуре OVERLAPPED, и ReadFile может
возвратить значение прежде, чем операция
чтения будет закончена. В этом случае, ReadFile
возвращает значение ЛОЖЬ (FALSE), а функция
GetLastError

возвращает значение ERROR_IO_PENDING.
Это дает возможность вызывающему процессу
продолжиться, в то время как операция
чтения заканчивается. Событие,
определяемое в структуре OVERLAPPED
устанавливается в сигнальное состояние
после завершения операции чтения. Вызывающая
программа должна корректировать
местоположение указателя позиции в файле
после завершения работы.

Функция ReadFile сбрасывает
событие, указанное членом hEvent
структуры OVERLAPPED в
несигнальное состояние, когда она начинает
операцию ввода-вывода (I/O). Поэтому, нет
необходимости для вызывающей программы,
чтобы делать так.

Если hFile не
открывался с флажком  FILE_FLAG_OVERLAPPED,
а lpOverlapped — значение ПУСТО (NULL),
операции чтения начинается в текущей
позиции файла и ReadFile не возвращает
значения до тех пор, пока операция не будет
закончена. Система модернизирует
указатель позиции в файле после завершения

работы.

Если hFile не открывался с FILE_FLAG_OVERLAPPED,
а lpOverlapped — не ПУСТО
(NULL),  операция чтения стартует при
смещении, указанном в структуре OVERLAPPED.
ReadFile не возвращает
значение до тех пор, пока операция чтения не
завершилась. Система модернизирует позицию
указателя  в файле после завершения
работы.

Windows 95/98/Me: Для
операций с файлами, дисками, каналами или
почтовыми ящиками в ядре Windows, этим
параметром должно быть значение ПУСТО (NULL);
указатель на структуру OVERLAPPED порождает
вызов, который завершиться ошибкой. Тем не
менее, Windows 95/98/Me поддерживает
асинхронные операции на последовательных и
параллельных портах.

Возвращаемые значения

Функция ReadFile возвращает значение тогда,
когда выполнено одно из ниже
перечисленных  условий: 

— операция записи завершается на записывающем
конце канала, 
— затребованное число байтов прочитано, 
— или происходит ошибка.

Если функция завершается успешно,
величина возвращаемого значения — не ноль.

Если функция завершается с ошибкой,
величина возвращаемого значения — ноль.
Чтобы получить дополнительные сведения об
ошибке, вызовите GetLastError.

Если величина возвращаемого значения — не
ноль, а число прочитанных байтов равняется
нулю, указатель файла был за пределами
текущего конца файла на момент операции
чтения. Однако, если файл был открыт с
флажком FILE_FLAG_OVERLAPPED, и lpOverlapped имеет 
значение не ПУСТО (NULL), величина
возвращаемого значения — ноль, а GetLastError
возвращает ошибку ERROR_HANDLE_EOF, когда
указатель файла проходит вне текущего
конца файла.



Замечания

Если часть файла блокирована другим
процессом, а операция чтения накладывается
на блокированную часть, эта функция
завершается ошибкой.

Когда работа с файлами открывается с
флажком FILE_FLAG_NO_BUFFERING, приложение должно
соответствовать некоторым требованиям:

  • Доступ  к файлу
    должен начаться при смещениях байтов в
    пределах файла, которые должны быть
    целыми числами кратными размеру сектора
    тома. Чтобы выяснить размер сектора тома,
    вызовите функцию GetDiskFreeSpace.
  • Доступ  к файлу
    должен быть числом байтов, которое
    является целым числом кратным размеру
    сектора тома. Например, если размер
    сектора — 512 байтов, приложение может
    запросить для чтения и записи  512, 1024
    или 2048 байтов, но не 335, 981 или 7171 байт.
  • Адреса буферов
    для операций чтения и записи должны
    выравниваться кратно сектору (выравниваются
    адреса в памяти, которые являются целыми числами, кратными размеру сектора тома).
    Один из способов выравнивания буфера
    кратно сектору, является использование
    функции VirtualAlloc, которая назначает буфера.
    Эта функция выделяет память, выравнивая
    их по адресам, которые
    являются целыми числами, кратными
    размеру страницы памяти  системы. Поскольку
    размеры и страницы памяти, и  сектора тома
    являются степенью 2, память, выровненная
    кратно размеру страницы памяти системы также
    выравнивается кратно и размеру сектора
    тома.

Доступ к буферу ввода, в то время как
операция чтения использует этот буфер,
может привести к искажению прочитанных
данных в буфер. Приложения не должны читать
из, записывать в, перераспределять или
освобождать буфер ввода, который использует
операция
чтения  до тех пор, пока она не завершится.

Символы могут читаться из буфера ввода
консоли при помощи использования функции
ReadFile
с дескриптором консольного ввода
данных. Консольный режим работы
обуславливает правильное поведение
функции ReadFile.

Если именованный канал читается в режиме
передачи сообщений, а длина следующего
сообщения больше, чем это устанавливается
параметром nNumberOfBytesToRead, ReadFile возвращает
значение ЛОЖЬ (FALSE), а GetLastError возвращает
ошибку ERROR_MORE_DATA. Остаток сообщения может
быть прочитан последующим вызовом 
функции ReadFile или PeekNamedPipe.

При чтении в устройстве
обмена информацией (коммуникационном),
поведение ReadFile управляется текущими
коммуникационными задержками как
установлено и возвращено обратно
использованием функций SetCommTimeouts
и GetCommTimeouts.
Непредсказуемые результаты могут
произойти, если Вы будете не в состоянии
установить значения времени простоя. Для
получения дополнительной информации о
коммуникационных блокировках по времени,
см. статью о структуре COMMTIMEOUTS.

Если ReadFile пытается
читать из почтового слота, буфер которого
является слишком маленьким, функция
возвращает значение ЛОЖЬ (FALSE), а GetLastError
возвращает ошибку ERROR_INSUFFICIENT_BUFFER.

Если дескриптор
анонимного  канала записи был закрыт, а
функция ReadFile пытается читать используя
дескриптор соответствующего анонимного
канала чтения, функция возвращает значение
ЛОЖЬ (FALSE), а GetLastError возвращает ошибку ERROR_BROKEN_PIPE.

Функция ReadFile может
завершиться ошибкой и возвратить значение ERROR_INVALID_USER_BUFFER
или ERROR_NOT_ENOUGH_MEMORY всякий
раз, когда имеется слишком много ожидающих
обработки асинхронных запросов ввода —
вывода.

Код проверки ReadFile
положения метки конца файла (eof)
различается для синхронных и асинхронных
операций чтения.

Когда синхронная операция
чтения достигает конца файла, ReadFile
возвращает значение ИСТИНА (TRUE) и
устанавливает в параметре *lpNumberOfBytesRead 
нуль. Нижеследующий типовой код проверяет
метку конца файла для синхронной операции
чтения:

// Делается попытка произвести синхронную операцию чтения. 
bResult = ReadFile(hFile, &inBuffer, nBytesToRead,
                   &nBytesRead, NULL) ; 
// Проверяем не конец ли это файла. 
if (bResult &&  nBytesRead == 0, ) 
{ 
    // Мы достигли конца файла. 
} 

Асинхронная операция
чтения может встретиться с концом файла в
течение инициализации вызова  ReadFile,
или в ходе последующей асинхронной
операции.

Если EOF
обнаруживается  функцией ReadFile во
время асинхронной операции чтения, ReadFile
возвращает значение ЛОЖЬ (FALSE), а GetLastError
возвращает ошибку ERROR_HANDLE_EOF.

Если EOF обнаруживается
в ходе последующей асинхронной операции,
происходит вызов функции GetOverlappedResult,
чтобы получить в результате этой операции
возвращенное значение ЛОЖЬ (FALSE), а GetLastError
возвратит ошибку ERROR_HANDLE_EOF.

Чтобы отменить  все
ждущие обработки асинхронные операции
ввода-вывода (I/O), используйте функцию CancelIo.
Эта функция  отменяет только операции,
порождаемые вызывающим потоком для
заданного дескриптора файла. Отмененные
операции ввода-вывода (I/O) завершаются
ошибкой ERROR_OPERATION_ABORTED.

Если Вы пытаетесь читать
из накопителя на гибких дисках, который не
имеет дискеты, система показывает на экране
окно сообщения, предлагающее пользователю
повторить  операцию. Чтобы
воспрепятствовать системе показывать это
окно, вызовите функцию SetErrorMode
с флажком SEM_NOOPENFILEERRORBOX.

Пример кода

Нижеследующий типовой код
иллюстрирует проверку на метку конца файла
для асинхронной операции чтения:

OVERLAPPED gOverlapped;
// подготавливаем поля структуры асинхронной операции
gOverLapped.Offset     = 0; 
gOverLapped.OffsetHigh = 0; 
gOverLapped.hEvent     = hEvent; 
 
// пытаемся провести асинхронную операцию чтения
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, 
    &gOverlapped) ; 
 
// если возникает проблема или асинхронная операция
// все еще ожидает обработки ... 
if (!bResult) 
{ 
    // решаем что делать с кодом ошибки
    switch (dwError = GetLastError()) 
    { 
        case ERROR_HANDLE_EOF: 
        { 
            // мы достигли конца файла 
            // в течение вызова к ReadFile 
 
            // код обрабатывается так-то
        } 
 
        case ERROR_IO_PENDING: 
        { 
            // асинхронный ввод-вывод все еще происходит 
 
            // сделаем кое-что пока он идет 
            GoDoSomethingElse() ; 
 
            // проверим результат работы асинхронного чтения 
            bResult = GetOverlappedResult(hFile, &gOverlapped, 
                &nBytesRead, FALSE) ; 
 
            // если возникла проблема ... 
            if (!bResult) 
            { 
                // решаем что делать с кодом ошибки
                switch (dwError = GetLastError()) 
                { 
                    case ERROR_HANDLE_EOF: 
                    { 
                        // мы достигли конца файла
                        // в ходе асинхронной
                        // операции
                    } 
 
                  // решаем что делать с другими случаями ошибок
                }// конец процедуры switch (dwError = GetLastError())
            } 
        } // конец процедуры case 
 
        // решаем что делать с другими случаями ошибок 
 
    } // конец процедуры switch (dwError = GetLastError()) 
} // конец процедуры if 

Смотри также 

Обзор Управление файлами,  Функции для
файлового ввода-вывода (I/O)
, CancelIo,
CreateFile
GetCommTimeoutsGetOverlappedResult,
GetQueuedCompletionStatus

OVERLAPPEDPeekNamedPipe,
ReadFileEx

SetCommTimeoutsSetErrorMode,
WriteFile






















Размещение
и совместимость 
ReadFile

К

Windows XP

Да 

л

Windows 2000 Professional

Да

и

Windows NT Workstation

Да

е

Windows Me

Да

н

Windows 98

Да

т

Windows 95

Да

 
С

Windows Server 2003

Да

е Windows
2000 Server
Да
р Windows
NT Server
Да
в    
е    
р    

Используемая
библиотека

Kernel32.lib

Используемая
DLL
 Заголовочный
файл
 

— объявлено в

Winbase.h

 —
включено в

Windows.h

 Unicode

 Замечания
по платформе

Не имеется

Hosted by uCoz

Я создаю программу для заполнения диска фиктивной файловой системой.

В настоящее время я пишу файлы с переменными размерами с помощью WriteFile.

        WriteFile(hFile, FileData, i * 1024, &dwWrote, NULL);
        err = GetLastError();

err возвращает # 1784, что означает

Загруженный буфер пользователя недействителен для запрошенной операции. ERROR_INVALID_USER_BUFFER

Итак, для первых 24 файлов работает операция записи. Для файла № 25 операция записи не выполняется.
Файлы все еще созданы, но функция WriteFile не заполняет файлы.

Любые идеи о том, как пройти мимо ERROR_INVALID_USER_BUFFER?

Каждая ссылка, которую я могу найти, связана с ошибкой программ, и я не могу понять, как она связана с проблемой, которую я испытываю.

EDIT:

FileData = (char *) malloc(sizeof(char) * (size_t)k * 1024);
memset(FileData, 245, sizeof(char) * (size_t)k * 1024);

FileData устанавливается и назначается размеру максимального ожидаемого буфера.
i — это переменная цикла, которая выполняет итерацию до тех пор, пока она не увеличится до максимального размера (k).

I’d be happy to help in any way I can. I’m hoping to use this for my master’s research, so I’m definitely interested in getting this working.

I updated to your latest version of libusb and I’m having a different problem now. I now get libusb: error [windows_transfer_callback] detected I/O error 87: [87] The parameter is incorrect. and the program crashes at the following (in my own program):

capture

I had to disable the libusb_detach_kernel_driver portion of ps4eye.cpp (link), otherwise I get «not supported» errors. Apparently the detach code isn’t supported in Windows. Additionally, I had to disable this line after enabling debug messages since ctrl.bInterfaceNumber isn’t initialized.

I tried doing all this on a fresh computer to check about the interfaces. USB_BOOT shows fine, and when uploading the firmware, Windows reconnects to the camera and automatically installs a system driver:

capture

At this point, only Interface 0 was visible, same as your situation. I tried running the SDL test tool and it tells me that the device can’t be opened, which I gather is fine since I’m supposed to replace the composite parent with libusbK.

After replacing the composite parent with libusbK, I get the [windows_transfer_callback] error above when using the SDL test tool, but only when running in Release configuration. In Debug, the program will run without complaining, but the screen is black.

Let me know if there’s any other way I can help!

Hi qwerty12, first off all, again thank you for your help without you it would have taken me very long to get so far. It have taken me even these days to figure it out what you have done. :)

Thx for the comments they helped me, i just deleted the ones i understand, I added also a additional function to get the Device Instance ID.

It’s not necessary because an implicit conversion takes place on assigment isn’t it?

— [line55-56] you added a comma before your DllCall and NumPut
— [line102] the asterix symbol before the lpHardwareID in the while condition
— [line115-120] If the DllCall «CM_Get_Device_IDW» fails LastError is 0 in the MsgBox dialogue, but the DllCall returns 0 if it succeed

Code: Select all

; /////////////////////////////// INFO /////////////////////////////////////////
/*
Identify USB devices

Infos:
https://docs.microsoft.com/de-de/windows-hardware/drivers/install/device-information-sets

*/
; ////////////////////////////// AHK FLAGS /////////////////////////////////////
#NoEnv
; #Warn
SendMode Input
SetWorkingDir %A_ScriptDir%

; //////////////////////////////// FLAGS ///////////////////////////////////////
; Setupapi.h
DIGCF_DEFAULT :=          0x00000001  ; only valid with DIGCF_DEVICEINTERFACE
DIGCF_PRESENT :=          0x00000002
DIGCF_ALLCLASSES :=       0x00000004
DIGCF_PROFILE :=          0x00000008
DIGCF_DEVICEINTERFACE :=  0x00000010

;Devpkey.h
; -
; ////////////////////////////// MAIN //////////////////////////////////////////

; Ensure setupapi.dll remains loaded between each DllCall
hModule := DllCall("LoadLibrary", "Str", "setupapi.dll", "Ptr")
if (!hModule) {
	MsgBox % "LoadLibrary failed. A_LastError: " . A_LastError
	ExitApp 1
}

; get handle (DeviceInfoList)
handle := DllCall("setupapi.dllSetupDiGetClassDevs", "Ptr", 0, "Str", "USB", "Ptr", 0, "UInt", DIGCF_PRESENT | DIGCF_ALLCLASSES, "Ptr")
If (!handle) {
    MsgBox SetupDiGetClassDevs call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
}

; enumerate devices from set

; DEFINE
; ¯¯¯¯¯¯

; array holding file string
Member := Object()

; structure SP_DEVINFO_DATA (SP_DEVINFO_DATA structure)
StructSize := 4 + 16 + 4 + A_PtrSize
VarSetCapacity(SP_DEVINFO_DATA, StructSize, 0)
NumPut(StructSize, SP_DEVINFO_DATA, 0, "UInt") ; fill in cbSize

; structure DEVPKEY_Device_DeviceDesc (DEVPROPKEY structure)
VarSetCapacity(DEVPKEY_Device_DeviceDesc, 20)
,DllCall("ole32CLSIDFromString", "WStr", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "Ptr", &DEVPKEY_Device_DeviceDesc) ; fill in fmtid member of DEVPROPKEY struct
,NumPut(2, DEVPKEY_Device_DeviceDesc, 16, "UInt") ; fill in pid

; structure DEVPKEY_Device_FriendlyName (DEVPROPKEY structure)
VarSetCapacity(DEVPKEY_Device_FriendlyName, 20) ; you might consider looking at DEVPKEY_Device_BusReportedDeviceDesc too/instead
,DllCall("ole32CLSIDFromString", "WStr", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "Ptr", &DEVPKEY_Device_FriendlyName)
,NumPut(14, DEVPKEY_Device_FriendlyName, 16, "UInt")

; structure DEVPKEY_Device_HardwareIds (DEVPROPKEY structure)
VarSetCapacity(DEVPKEY_Device_HardwareIds, 20)
,DllCall("ole32CLSIDFromString", "WStr", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "Ptr", &DEVPKEY_Device_HardwareIds)
,NumPut(3, DEVPKEY_Device_HardwareIds, 16, "UInt")

; ENUMERATE
; ¯¯¯¯¯¯¯¯¯

Loop
{
    ; get item from list
    If (!DllCall("setupapi.dllSetupDiEnumDeviceInfo", "Ptr", handle, "UInt", A_Index - 1, "Ptr", &SP_DEVINFO_DATA)) {
        If (A_LastError != 259) ;ERROR_NO_MORE_ITEMS
            MsgBox SetupDiEnumDeviceInfo call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%`nA_Index: %A_Index%
		break
    }

	; Empty all of these variables so that the values obtained from previous calls aren't used if SetupDiGetDevicePropertyW fails
	wszDeviceDesc := wszFriendlyName := hardwareIDs := DeviceID := ""

	if (!DllCall("setupapiSetupDiGetDevicePropertyW", "Ptr", handle, "Ptr", &SP_DEVINFO_DATA, "Ptr", &DEVPKEY_Device_DeviceDesc, "UInt*", PropType, "Ptr", 0, "UInt", 0, "UInt*", RequiredSize, "UInt", 0) && A_LastError == 122) { ; ERROR_INSUFFICIENT_BUFFER
		VarSetCapacity(wszDeviceDesc, RequiredSize)
		if (!DllCall("setupapiSetupDiGetDevicePropertyW", "Ptr", handle, "Ptr", &SP_DEVINFO_DATA, "Ptr", &DEVPKEY_Device_DeviceDesc, "UInt*", PropType, "WStr", wszDeviceDesc, "UInt", RequiredSize, "Ptr", 0, "UInt", 0))
			MsgBox SetupDiGetDevicePropertyW (DEVPKEY_Device_DeviceDesc) call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%`nA_Index: %A_Index%
	}

	if (!DllCall("setupapiSetupDiGetDevicePropertyW", "Ptr", handle, "Ptr", &SP_DEVINFO_DATA, "Ptr", &DEVPKEY_Device_FriendlyName, "UInt*", PropType, "Ptr", 0, "UInt", 0, "UInt*", RequiredSize, "UInt", 0) && A_LastError == 122) { ; ERROR_INSUFFICIENT_BUFFER
		VarSetCapacity(wszFriendlyName, RequiredSize)
		if (!DllCall("setupapiSetupDiGetDevicePropertyW", "Ptr", handle, "Ptr", &SP_DEVINFO_DATA, "Ptr", &DEVPKEY_Device_FriendlyName, "UInt*", PropType, "WStr", wszFriendlyName, "UInt", RequiredSize, "Ptr", 0, "UInt", 0))
			MsgBox SetupDiGetDevicePropertyW (DEVPKEY_Device_FriendlyName) call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%`nA_Index: %A_Index%
	}

	if (!DllCall("setupapiSetupDiGetDevicePropertyW", "Ptr", handle, "Ptr", &SP_DEVINFO_DATA, "Ptr", &DEVPKEY_Device_HardwareIds, "UInt*", PropType, "Ptr", 0, "UInt", 0, "UInt*", RequiredSize, "UInt", 0) && A_LastError == 122) {
		VarSetCapacity(wmszHardwareIDs, RequiredSize)
		if (!DllCall("setupapiSetupDiGetDevicePropertyW", "Ptr", handle, "Ptr", &SP_DEVINFO_DATA, "Ptr", &DEVPKEY_Device_HardwareIds, "UInt*", PropType, "Ptr", &wmszHardwareIDs, "UInt", RequiredSize, "Ptr", 0, "UInt", 0))
			MsgBox SetupDiGetDevicePropertyW (DEVPKEY_Device_HardwareIds) call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%`nA_Index: %A_Index%
		else {
			; Reading from this string is a little different, as it's a string containing multiple strings, delimited by a standard , but with a  at the very end
			lpHardwareID := &wmszHardwareIDs
			while (*lpHardwareID) {
				wszHardwareID := StrGet(lpHardwareID,, "UTF-16") ; Read string from buffer up to 
				hardwareIDs .= wszHardwareID . ", " ; append said string to new string, delimited by a comma and space pair
				lpHardwareID += (DllCall("ntdllwcslen", "Ptr", lpHardwareID, "CDecl UPtr") + 1) * 2 ; Advance to next null-terminated string
			}
			if ((cchhardwareIDs := StrLen(hardwareIDs)) && cchhardwareIDs > 2)
				NumPut(0, hardwareIDs, (cchhardwareIDs - 2) * (A_IsUnicode ? 2 : 1), A_IsUnicode ? "UShort" : "Char") ; Remove the last extra comma and space pair
		}
	}

    DevInst := NumGet(SP_DEVINFO_DATA, 20, "UInt")
    If (!DllCall("Cfgmgr32CM_Get_Device_ID_Size", "UInt*", RequiredSize, "UInt", DevInst, "UInt", 0)) {
        VarSetCapacity(wszDeviceID, RequiredSize)
        If (!DllCall("Cfgmgr32CM_Get_Device_IDW", "UInt", DevInst, "Ptr", &wszDeviceID, "UInt", RequiredSize, "UInt", 0)) {
            lpDeviceID := &wszDeviceID           
            DeviceID := StrGet(lpDeviceID,, "UTF-16")
        }
        else
            MsgBox CM_Get_Device_IDW call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%`nA_Index: %A_Index%
    }

	; save value in array - I use Format here, but it doesn't add much. I guess plain string concatenation is a possibility...
	Member.Push(Format("{1:s}{2:s}{3:s}{4:s}"   , wszDeviceDesc ? wszDeviceDesc . " " : ""
                                                , wszFriendlyName ? "(" . wszFriendlyName . ")" : ""
                                                , hardwareIDs ? " - " . hardwareIDs : ""
                                                , DeviceID ? " - " . DeviceID : ""))                                                                         
}


; destroy handle (DeviceInfoList)
DllCall("setupapiSetupDiDestroyDeviceInfoList", "Ptr", handle)  ; you don't need error checking here: if it frees, it frees. No point in otherwise fretting. You already checked to see if handle != NULL and you got the DllCall right for this function

; write to file
for _, add_line in Member
    FileAppend, %add_line%`n, device_enumeration.txt, UTF-16

; Unload setupapi.dll, Cfgmgr32.dll
DllCall("FreeLibrary", "Ptr", hModule)

Понравилась статья? Поделить с друзьями:
  • Error invalid use of void expression
  • Error invalid use of this in non member function
  • Error invalid use of non static member function thread
  • Error invalid use of member function did you forget the
  • Error invalid use of incomplete type