diff --git a/examples/iscsiclient.c b/examples/iscsiclient.c index 006cd04..f0faefa 100644 --- a/examples/iscsiclient.c +++ b/examples/iscsiclient.c @@ -13,13 +13,20 @@ */ /* This is the host/port we connect to.*/ -#define TARGET "127.0.0.1:3260" +#define TARGET "10.1.1.116:3260" + +#if defined(WIN32) +#include +#pragma comment(lib, "ws2_32.lib") +WSADATA wsaData; +#else +#include +#endif #include #include #include #include -#include #include "iscsi.h" #include "scsi-lowlevel.h" @@ -502,6 +509,13 @@ int main(int argc _U_, char *argv[] _U_) struct client_state clnt; printf("iscsi client\n"); +#if defined(WIN32) + if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { + printf("Failed to start Winsock2\n"); + exit(10); + } +#endif + memset(&clnt, 0, sizeof(clnt)); diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 4db81e5..fd4c5b7 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -19,6 +19,11 @@ #include +#if defined(WIN32) +#include +#define ssize_t SSIZE_T +#endif + #ifndef discard_const #define discard_const(ptr) ((void *)((intptr_t)(ptr))) #endif diff --git a/include/iscsi.h b/include/iscsi.h index 1f0b938..e5b835c 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -19,6 +19,12 @@ #include +#if defined(WIN32) +#define EXTERN __declspec( dllexport ) +EXTERN int poll(struct pollfd *fds, int nfsd, int timeout); +#else +#define EXTERN +#endif struct iscsi_context; struct sockaddr; @@ -39,20 +45,20 @@ struct sockaddr; /* * Returns the file descriptor that libiscsi uses. */ -int iscsi_get_fd(struct iscsi_context *iscsi); +EXTERN int iscsi_get_fd(struct iscsi_context *iscsi); /* * Returns which events that we need to poll for for the iscsi file descriptor. */ -int iscsi_which_events(struct iscsi_context *iscsi); +EXTERN int iscsi_which_events(struct iscsi_context *iscsi); /* * Called to process the events when events become available for the iscsi * file descriptor. */ -int iscsi_service(struct iscsi_context *iscsi, int revents); +EXTERN int iscsi_service(struct iscsi_context *iscsi, int revents); /* * How many commands are in flight. */ -int iscsi_queue_length(struct iscsi_context *iscsi); +EXTERN int iscsi_queue_length(struct iscsi_context *iscsi); /* * To set tcp keepalive for the session @@ -85,8 +91,8 @@ struct iscsi_url { * * The returned structure is freed by calling iscsi_destroy_url() */ -struct iscsi_url *iscsi_parse_full_url(struct iscsi_context *iscsi, const char *url); -void iscsi_destroy_url(struct iscsi_url *iscsi_url); +EXTERN struct iscsi_url *iscsi_parse_full_url(struct iscsi_context *iscsi, const char *url); +EXTERN void iscsi_destroy_url(struct iscsi_url *iscsi_url); /* * This function is used to parse an iSCSI Portal URL into a iscsi_url structure. @@ -106,13 +112,13 @@ void iscsi_destroy_url(struct iscsi_url *iscsi_url); * * The returned structure is freed by calling iscsi_destroy_url() */ -struct iscsi_url * +EXTERN struct iscsi_url * iscsi_parse_portal_url(struct iscsi_context *iscsi, const char *url); /* * This function returns a description of the last encountered error. */ -const char *iscsi_get_error(struct iscsi_context *iscsi); +EXTERN const char *iscsi_get_error(struct iscsi_context *iscsi); /* * Create a context for an ISCSI session. @@ -122,7 +128,7 @@ const char *iscsi_get_error(struct iscsi_context *iscsi); * 0: success * <0: error */ -struct iscsi_context *iscsi_create_context(const char *initiator_name); +EXTERN struct iscsi_context *iscsi_create_context(const char *initiator_name); /* * Destroy an existing ISCSI context and tear down any existing connection. @@ -133,7 +139,7 @@ struct iscsi_context *iscsi_create_context(const char *initiator_name); * 0: success * <0: error */ -int iscsi_destroy_context(struct iscsi_context *iscsi); +EXTERN int iscsi_destroy_context(struct iscsi_context *iscsi); /* * Set an optional alias name to identify with when connecting to the target @@ -142,7 +148,7 @@ int iscsi_destroy_context(struct iscsi_context *iscsi); * 0: success * <0: error */ -int iscsi_set_alias(struct iscsi_context *iscsi, const char *alias); +EXTERN int iscsi_set_alias(struct iscsi_context *iscsi, const char *alias); /* * Set the iqn name of the taqget to login to. @@ -153,13 +159,13 @@ int iscsi_set_alias(struct iscsi_context *iscsi, const char *alias); * 0: success * <0: error */ -int iscsi_set_targetname(struct iscsi_context *iscsi, const char *targetname); +EXTERN int iscsi_set_targetname(struct iscsi_context *iscsi, const char *targetname); /* * This function returns any target address supplied in a login response when * the target has moved. */ -const char *iscsi_get_target_address(struct iscsi_context *iscsi); +EXTERN const char *iscsi_get_target_address(struct iscsi_context *iscsi); /* Type of iscsi sessions. Discovery sessions are used to query for what * targets exist behind the portal connected to. Normal sessions are used to @@ -178,7 +184,7 @@ enum iscsi_session_type { * 0: success * <0: error */ -int iscsi_set_session_type(struct iscsi_context *iscsi, +EXTERN int iscsi_set_session_type(struct iscsi_context *iscsi, enum iscsi_session_type session_type); @@ -201,20 +207,20 @@ enum iscsi_header_digest { * 0: success * <0: error */ -int iscsi_set_header_digest(struct iscsi_context *iscsi, +EXTERN int iscsi_set_header_digest(struct iscsi_context *iscsi, enum iscsi_header_digest header_digest); /* * Specify the username and password to use for chap authentication */ -int iscsi_set_initiator_username_pwd(struct iscsi_context *iscsi, +EXTERN int iscsi_set_initiator_username_pwd(struct iscsi_context *iscsi, const char *user, const char *passwd); /* * check if the context is logged in or not */ -int iscsi_is_logged_in(struct iscsi_context *iscsi); +EXTERN int iscsi_is_logged_in(struct iscsi_context *iscsi); enum scsi_status { @@ -258,7 +264,7 @@ typedef void (*iscsi_command_cb)(struct iscsi_context *iscsi, int status, * The callback will NOT be invoked if the session is explicitely torn down * through a call to iscsi_disconnect() or iscsi_destroy_context(). */ -int iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, +EXTERN int iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, iscsi_command_cb cb, void *private_data); /* @@ -269,7 +275,7 @@ int iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, * <0 if there was an error. * */ -int iscsi_connect_sync(struct iscsi_context *iscsi, const char *portal); +EXTERN int iscsi_connect_sync(struct iscsi_context *iscsi, const char *portal); /* @@ -297,7 +303,7 @@ int iscsi_connect_sync(struct iscsi_context *iscsi, const char *portal); * The callback will NOT be invoked if the session is explicitely torn down * through a call to iscsi_disconnect() or iscsi_destroy_context(). */ -int iscsi_full_connect_async(struct iscsi_context *iscsi, const char *portal, +EXTERN int iscsi_full_connect_async(struct iscsi_context *iscsi, const char *portal, int lun, iscsi_command_cb cb, void *private_data); /* @@ -309,7 +315,7 @@ int iscsi_full_connect_async(struct iscsi_context *iscsi, const char *portal, * 0 if the cconnect was successful. * <0 if there was an error. */ -int iscsi_full_connect_sync(struct iscsi_context *iscsi, const char *portal, +EXTERN int iscsi_full_connect_sync(struct iscsi_context *iscsi, const char *portal, int lun); /* @@ -320,7 +326,7 @@ int iscsi_full_connect_sync(struct iscsi_context *iscsi, const char *portal, * 0 disconnect was successful * <0 error */ -int iscsi_disconnect(struct iscsi_context *iscsi); +EXTERN int iscsi_disconnect(struct iscsi_context *iscsi); /* * Asynchronous call to perform an ISCSI login. @@ -337,7 +343,7 @@ int iscsi_disconnect(struct iscsi_context *iscsi); * ISCSI_STATUS_CANCELLED: login was aborted. Command_data is NULL. * ISCSI_STATUS_ERROR : login failed. Command_data is NULL. */ -int iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb, +EXTERN int iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb, void *private_data); /* @@ -347,7 +353,7 @@ int iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb, * 0 if the login was successful * <0 if there was an error. */ -int iscsi_login_sync(struct iscsi_context *iscsi); +EXTERN int iscsi_login_sync(struct iscsi_context *iscsi); /* @@ -364,7 +370,7 @@ int iscsi_login_sync(struct iscsi_context *iscsi); * NULL. * ISCSI_STATUS_CANCELLED: logout was aborted. Command_data is NULL. */ -int iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb, +EXTERN int iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb, void *private_data); /* @@ -374,7 +380,7 @@ int iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb, * 0 if the logout was successful * <0 if there was an error. */ -int iscsi_logout_sync(struct iscsi_context *iscsi); +EXTERN int iscsi_logout_sync(struct iscsi_context *iscsi); /* @@ -397,7 +403,7 @@ int iscsi_logout_sync(struct iscsi_context *iscsi); * freed once the callback returns. * ISCSI_STATUS_CANCELLED: Discovery was aborted. Command_data is NULL. */ -int iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb, +EXTERN int iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb, void *private_data); struct iscsi_discovery_address { @@ -422,7 +428,7 @@ struct iscsi_discovery_address { * the server. * ISCSI_STATUS_CANCELLED: Discovery was aborted. Command_data is NULL. */ -int iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, +EXTERN int iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, unsigned char *data, int len, void *private_data); struct scsi_task; @@ -456,28 +462,28 @@ enum iscsi_task_mgmt_funcs { * The callback will NOT be invoked if the session is explicitely torn down * through a call to iscsi_disconnect() or iscsi_destroy_context(). */ -int +EXTERN int iscsi_task_mgmt_async(struct iscsi_context *iscsi, int lun, enum iscsi_task_mgmt_funcs function, uint32_t ritt, uint32_t rcmdscn, iscsi_command_cb cb, void *private_data); -int +EXTERN int iscsi_task_mgmt_abort_task_async(struct iscsi_context *iscsi, struct scsi_task *task, iscsi_command_cb cb, void *private_data); -int +EXTERN int iscsi_task_mgmt_abort_task_set_async(struct iscsi_context *iscsi, uint32_t lun, iscsi_command_cb cb, void *private_data); -int +EXTERN int iscsi_task_mgmt_lun_reset_async(struct iscsi_context *iscsi, uint32_t lun, iscsi_command_cb cb, void *private_data); -int +EXTERN int iscsi_task_mgmt_target_warm_reset_async(struct iscsi_context *iscsi, iscsi_command_cb cb, void *private_data); -int +EXTERN int iscsi_task_mgmt_target_cold_reset_async(struct iscsi_context *iscsi, iscsi_command_cb cb, void *private_data); @@ -519,13 +525,13 @@ struct iscsi_data { * * Setting the ISID can only be done before loggin in to the target. */ -int +EXTERN int iscsi_set_isid_oui(struct iscsi_context *iscsi, uint32_t oui, uint32_t qualifier); -int +EXTERN int iscsi_set_isid_en(struct iscsi_context *iscsi, uint32_t en, uint32_t qualifier); -int +EXTERN int iscsi_set_isid_random(struct iscsi_context *iscsi, uint32_t rnd, uint32_t qualifier); -int +EXTERN int iscsi_set_isid_reserved(struct iscsi_context *iscsi); @@ -541,7 +547,7 @@ iscsi_set_isid_reserved(struct iscsi_context *iscsi); * from the callback. */ -int iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, +EXTERN int iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, struct scsi_task *task, iscsi_command_cb cb, struct iscsi_data *data, void *private_data); @@ -551,41 +557,41 @@ int iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, * These async functions return a scsi_task structure, or NULL if the command failed. * This structure can be used by task management functions to abort the task or a whole task set. */ -struct scsi_task * +EXTERN struct scsi_task * iscsi_reportluns_task(struct iscsi_context *iscsi, int report_type, int alloc_len, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_testunitready_task(struct iscsi_context *iscsi, int lun, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_inquiry_task(struct iscsi_context *iscsi, int lun, int evpd, int page_code, int maxsize, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_readcapacity10_task(struct iscsi_context *iscsi, int lun, int lba, int pmi, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_synchronizecache10_task(struct iscsi_context *iscsi, int lun, int lba, int num_blocks, int syncnv, int immed, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_write10_task(struct iscsi_context *iscsi, int lun, unsigned char *data, uint32_t datalen, uint32_t lba, int fua, int fuanv, int blocksize, iscsi_command_cb cb, void *private_data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd, int pc, int page_code, int sub_page_code, unsigned char alloc_len, iscsi_command_cb cb, @@ -595,34 +601,34 @@ iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd, /* * Sync commands for SCSI */ -struct scsi_task * +EXTERN struct scsi_task * iscsi_scsi_command_sync(struct iscsi_context *iscsi, int lun, struct scsi_task *task, struct iscsi_data *data); -struct scsi_task * +EXTERN struct scsi_task * iscsi_reportluns_sync(struct iscsi_context *iscsi, int report_type, int alloc_len); -struct scsi_task * +EXTERN struct scsi_task * iscsi_testunitready_sync(struct iscsi_context *iscsi, int lun); -struct scsi_task * +EXTERN struct scsi_task * iscsi_inquiry_sync(struct iscsi_context *iscsi, int lun, int evpd, int page_code, int maxsize); -struct scsi_task * +EXTERN struct scsi_task * iscsi_read6_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize); -struct scsi_task * +EXTERN struct scsi_task * iscsi_read10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize); -struct scsi_task * +EXTERN struct scsi_task * iscsi_readcapacity10_sync(struct iscsi_context *iscsi, int lun, int lba, int pmi); -struct scsi_task * +EXTERN struct scsi_task * iscsi_synchronizecache10_sync(struct iscsi_context *iscsi, int lun, int lba, int num_blocks, int syncnv, int immed); @@ -648,7 +654,7 @@ iscsi_synchronizecache10_sync(struct iscsi_context *iscsi, int lun, int lba, * task->datain.size will be 0 and * task->datain.data will be NULL */ -int scsi_task_add_data_in_buffer(struct scsi_task *task, int len, unsigned char *buf); +EXTERN int scsi_task_add_data_in_buffer(struct scsi_task *task, int len, unsigned char *buf); #endif /* __iscsi_h__ */ diff --git a/include/md5.h b/include/md5.h index 100eecc..52ba252 100644 --- a/include/md5.h +++ b/include/md5.h @@ -23,9 +23,13 @@ #ifndef MD5_H #define MD5_H +#if defined(WIN32) +#else +#include +#endif + #include #include -#include #include #if (__BYTE_ORDER == __BIG_ENDIAN) # define WORDS_BIGENDIAN 1 diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h index 8eb3c95..ba47bfd 100644 --- a/include/scsi-lowlevel.h +++ b/include/scsi-lowlevel.h @@ -50,7 +50,7 @@ enum scsi_sense_key { SCSI_SENSE_MISCOMPARE = 0x0e }; -const char *scsi_sense_key_str(int key); +EXTERN const char *scsi_sense_key_str(int key); /* ascq */ #define SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE 0x2000 @@ -59,7 +59,7 @@ const char *scsi_sense_key_str(int key); #define SCSI_SENSE_ASCQ_LOGICAL_UNIT_NOT_SUPPORTED 0x2500 #define SCSI_SENSE_ASCQ_BUS_RESET 0x2900 -const char *scsi_sense_ascq_str(int ascq); +EXTERN const char *scsi_sense_ascq_str(int ascq); enum scsi_xfer_dir { @@ -152,14 +152,14 @@ struct scsi_task { struct scsi_data_buffer *in_buffers; }; -void scsi_free_scsi_task(struct scsi_task *task); -void scsi_set_task_private_ptr(struct scsi_task *task, void *ptr); -void *scsi_get_task_private_ptr(struct scsi_task *task); +EXTERN void scsi_free_scsi_task(struct scsi_task *task); +EXTERN void scsi_set_task_private_ptr(struct scsi_task *task, void *ptr); +EXTERN void *scsi_get_task_private_ptr(struct scsi_task *task); /* * TESTUNITREADY */ -struct scsi_task *scsi_cdb_testunitready(void); +EXTERN struct scsi_task *scsi_cdb_testunitready(void); /* @@ -174,7 +174,7 @@ struct scsi_reportluns_list { uint16_t luns[0]; }; -struct scsi_task *scsi_reportluns_cdb(int report_type, int alloc_len); +EXTERN struct scsi_task *scsi_reportluns_cdb(int report_type, int alloc_len); /* * READCAPACITY10 @@ -183,7 +183,7 @@ struct scsi_readcapacity10 { uint32_t lba; uint32_t block_size; }; -struct scsi_task *scsi_cdb_readcapacity10(int lba, int pmi); +EXTERN struct scsi_task *scsi_cdb_readcapacity10(int lba, int pmi); /* @@ -221,7 +221,7 @@ enum scsi_inquiry_peripheral_device_type { SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_UNKNOWN = 0x1f }; -const char *scsi_devtype_to_str(enum scsi_inquiry_peripheral_device_type type); +EXTERN const char *scsi_devtype_to_str(enum scsi_inquiry_peripheral_device_type type); enum scsi_version { SCSI_VERSION_SPC = 0x03, @@ -229,7 +229,7 @@ enum scsi_version { SCSI_VERSION_SPC3 = 0x05 }; -const char *scsi_version_to_str(enum scsi_version version); +EXTERN const char *scsi_version_to_str(enum scsi_version version); enum scsi_inquiry_tpgs { SCSI_INQUIRY_TPGS_NO_SUPPORT = 0x00, @@ -276,7 +276,7 @@ enum scsi_inquiry_pagecode { SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS = 0xB1 }; -const char *scsi_inquiry_pagecode_to_str(int pagecode); +EXTERN const char *scsi_inquiry_pagecode_to_str(int pagecode); struct scsi_inquiry_supported_pages { enum scsi_inquiry_peripheral_qualifier periperal_qualifier; @@ -295,7 +295,7 @@ struct scsi_inquiry_block_device_characteristics { int medium_rotation_rate; }; -struct scsi_task *scsi_cdb_inquiry(int evpd, int page_code, int alloc_len); +EXTERN struct scsi_task *scsi_cdb_inquiry(int evpd, int page_code, int alloc_len); struct scsi_inquiry_unit_serial_number { enum scsi_inquiry_peripheral_qualifier periperal_qualifier; @@ -317,7 +317,7 @@ enum scsi_protocol_identifier { SCSI_PROTOCOL_IDENTIFIER_ATA = 0x08 }; -const char *scsi_protocol_identifier_to_str(int identifier); +EXTERN const char *scsi_protocol_identifier_to_str(int identifier); enum scsi_codeset { SCSI_CODESET_BINARY = 0x01, @@ -325,7 +325,7 @@ enum scsi_codeset { SCSI_CODESET_UTF8 = 0x03 }; -const char *scsi_codeset_to_str(int codeset); +EXTERN const char *scsi_codeset_to_str(int codeset); enum scsi_association { SCSI_ASSOCIATION_LOGICAL_UNIT = 0x00, @@ -333,7 +333,7 @@ enum scsi_association { SCSI_ASSOCIATION_TARGET_DEVICE = 0x02 }; -const char *scsi_association_to_str(int association); +EXTERN const char *scsi_association_to_str(int association); enum scsi_designator_type { SCSI_DESIGNATOR_TYPE_VENDOR_SPECIFIC = 0x00, @@ -347,7 +347,7 @@ enum scsi_designator_type { SCSI_DESIGNATOR_TYPE_SCSI_NAME_STRING = 0x08 }; -const char *scsi_designator_type_to_str(int association); +EXTERN const char *scsi_designator_type_to_str(int association); struct scsi_inquiry_device_designator { struct scsi_inquiry_device_designator *next; @@ -465,7 +465,7 @@ struct scsi_mode_sense { struct scsi_mode_page *pages; }; -struct scsi_task *scsi_cdb_modesense6(int dbd, +EXTERN struct scsi_task *scsi_cdb_modesense6(int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, @@ -474,15 +474,15 @@ struct scsi_task *scsi_cdb_modesense6(int dbd, -int scsi_datain_getfullsize(struct scsi_task *task); -void *scsi_datain_unmarshall(struct scsi_task *task); +EXTERN int scsi_datain_getfullsize(struct scsi_task *task); +EXTERN void *scsi_datain_unmarshall(struct scsi_task *task); -struct scsi_task *scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize); -struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize); -struct scsi_task *scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fuanv, +EXTERN struct scsi_task *scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize); +EXTERN struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize); +EXTERN struct scsi_task *scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fuanv, int blocksize); -struct scsi_task *scsi_cdb_synchronizecache10(int lba, int num_blocks, +EXTERN struct scsi_task *scsi_cdb_synchronizecache10(int lba, int num_blocks, int syncnv, int immed); #endif /* __scsi_lowlevel_h__ */ diff --git a/lib/crc32c.c b/lib/crc32c.c index 1017235..0620aaf 100644 --- a/lib/crc32c.c +++ b/lib/crc32c.c @@ -14,7 +14,11 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ +#if defined(WIN32) +#else #include +#endif + #include "iscsi.h" #include "iscsi-private.h" diff --git a/lib/discovery.c b/lib/discovery.c index 294316b..f474ae7 100644 --- a/lib/discovery.c +++ b/lib/discovery.c @@ -15,10 +15,14 @@ along with this program; if not, see . */ +#if defined(WIN32) +#else +#include +#endif + #include #include #include -#include #include "iscsi.h" #include "iscsi-private.h" diff --git a/lib/init.c b/lib/init.c index 50a9021..826e04f 100644 --- a/lib/init.c +++ b/lib/init.c @@ -16,14 +16,18 @@ */ #define _GNU_SOURCE +#if defined(WIN32) +#else +#include +#include +#endif + #include #include #include -#include #include #include #include -#include #include #include "iscsi.h" #include "iscsi-private.h" @@ -50,7 +54,7 @@ iscsi_create_context(const char *initiator_name) iscsi->fd = -1; /* initialize to a "random" isid */ - iscsi_set_isid_random(iscsi, random(), 0); + iscsi_set_isid_random(iscsi, rand(), 0); /* assume we start in security negotiation phase */ iscsi->current_phase = ISCSI_PDU_LOGIN_CSG_SECNEG; @@ -242,8 +246,10 @@ iscsi_set_error(struct iscsi_context *iscsi, const char *error_string, ...) char *str; va_start(ap, error_string); - if (vasprintf(&str, error_string, ap) < 0) { + str = malloc(1024); + if (vsnprintf(str, 1024, error_string, ap) < 0) { /* not much we can do here */ + free(str); str = NULL; } diff --git a/lib/libiscsi.def b/lib/libiscsi.def new file mode 100644 index 0000000..0965f63 --- /dev/null +++ b/lib/libiscsi.def @@ -0,0 +1,84 @@ +LIBRARY libiscsi +EXPORTS +iscsi_get_fd +iscsi_which_events +iscsi_service +iscsi_queue_length +iscsi_parse_full_url +iscsi_destroy_url +iscsi_parse_portal_url +iscsi_get_error +iscsi_create_context +iscsi_destroy_context +iscsi_set_alias +iscsi_set_targetname +iscsi_get_target_address +iscsi_set_session_type +iscsi_set_header_digest +iscsi_set_initiator_username_pwd +iscsi_is_logged_in +iscsi_connect_async +iscsi_connect_sync +iscsi_full_connect_async +iscsi_full_connect_sync +iscsi_disconnect +iscsi_login_async +iscsi_login_sync +iscsi_logout_async +iscsi_logout_sync +iscsi_discovery_async +iscsi_nop_out_async +iscsi_task_mgmt_async +iscsi_task_mgmt_abort_task_async +iscsi_task_mgmt_abort_task_set_async +iscsi_task_mgmt_lun_reset_async +iscsi_task_mgmt_target_warm_reset_async +iscsi_task_mgmt_target_cold_reset_async +iscsi_set_isid_oui +iscsi_set_isid_en +iscsi_set_isid_random +iscsi_set_isid_reserved +iscsi_scsi_command_async +iscsi_reportluns_task +iscsi_testunitready_task +iscsi_inquiry_task +iscsi_readcapacity10_task +iscsi_synchronizecache10_task +iscsi_read6_task +iscsi_read10_task +iscsi_write10_task +iscsi_modesense6_task +iscsi_scsi_command_sync +iscsi_reportluns_sync +iscsi_testunitready_sync +iscsi_inquiry_sync +iscsi_readcapacity10_sync +iscsi_synchronizecache10_sync +iscsi_read6_sync +iscsi_read10_sync +poll +scsi_task_add_data_in_buffer +scsi_sense_key_str +scsi_sense_ascq_str +scsi_free_scsi_task +scsi_set_task_private_ptr +scsi_get_task_private_ptr +scsi_cdb_testunitready +scsi_reportluns_cdb +scsi_cdb_readcapacity10 +scsi_devtype_to_str +scsi_version_to_str +scsi_inquiry_pagecode_to_str +scsi_cdb_inquiry +scsi_protocol_identifier_to_str +scsi_codeset_to_str +scsi_association_to_str +scsi_designator_type_to_str +scsi_cdb_modesense6 +scsi_datain_getfullsize +scsi_datain_unmarshall +scsi_cdb_read6 +scsi_cdb_read10 +scsi_cdb_write10 +scsi_cdb_synchronizecache10 + diff --git a/lib/login.c b/lib/login.c index 5b2f5de..d9950ff 100644 --- a/lib/login.c +++ b/lib/login.c @@ -19,10 +19,15 @@ #define _GNU_SOURCE #endif +#if defined(WIN32) +#include +#else +#include +#endif + #include #include #include -#include #include "iscsi.h" #include "iscsi-private.h" #include "md5.h" @@ -38,11 +43,17 @@ iscsi_login_add_initiatorname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu return 0; } - if (asprintf(&str, "InitiatorName=%s", iscsi->initiator_name) == -1) { + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "InitiatorName=%s", iscsi->initiator_name) == -1) { +#else + if (snprintf(str, 1024, "InitiatorName=%s", iscsi->initiator_name) == -1) { +#endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } - +printf("initiatorname:%s\n", str); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -64,8 +75,14 @@ iscsi_login_add_alias(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return 0; } - if (asprintf(&str, "InitiatorAlias=%s", iscsi->alias) == -1) { + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "InitiatorAlias=%s", iscsi->alias) == -1) { +#else + if (snprintf(str, 1024, "InitiatorAlias=%s", iscsi->alias) == -1) { +#endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } @@ -96,8 +113,14 @@ iscsi_login_add_targetname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return -1; } - if (asprintf(&str, "TargetName=%s", iscsi->target_name) == -1) { + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "TargetName=%s", iscsi->target_name) == -1) { +#else + if (snprintf(str, 1024, "TargetName=%s", iscsi->target_name) == -1) { +#endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } @@ -207,9 +230,15 @@ iscsi_login_add_initialr2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return 0; } - if (asprintf(&str, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? +#else + if (snprintf(str, 1024, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? +#endif "No" : "Yes") == -1) { iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } @@ -234,9 +263,15 @@ iscsi_login_add_immediatedata(struct iscsi_context *iscsi, struct iscsi_pdu *pdu return 0; } - if (asprintf(&str, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? +#else + if (snprintf(str, 1024, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? +#endif "No" : "Yes") == -1) { iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } @@ -261,8 +296,14 @@ iscsi_login_add_maxburstlength(struct iscsi_context *iscsi, struct iscsi_pdu *pd return 0; } - if (asprintf(&str, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { +#else + if (snprintf(str, 1024, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { +#endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } @@ -286,8 +327,14 @@ iscsi_login_add_firstburstlength(struct iscsi_context *iscsi, struct iscsi_pdu * return 0; } - if (asprintf(&str, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { +#else + if (snprintf(str, 1024, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { +#endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } @@ -311,8 +358,14 @@ iscsi_login_add_maxrecvdatasegmentlength(struct iscsi_context *iscsi, struct isc return 0; } - if (asprintf(&str, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { + str = malloc(1024); +#if defined(WIN32) + if (_snprintf_s(str, 1024, 1024, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { +#else + if (snprintf(str, 1024, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { +#endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); + free(str); return -1; } @@ -658,6 +711,8 @@ iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb, struct iscsi_pdu *pdu; int transit; +printf("login async\n"); +fprintf(stderr, "login async\n"); if (iscsi->login_attempts++ > 10) { iscsi_set_error(iscsi, "login took too many tries." " giving up."); diff --git a/lib/nop.c b/lib/nop.c index 9d06920..325013a 100644 --- a/lib/nop.c +++ b/lib/nop.c @@ -15,8 +15,12 @@ along with this program; if not, see . */ -#include +#if defined(WIN32) +#else #include +#endif + +#include #include "iscsi.h" #include "iscsi-private.h" diff --git a/lib/pdu.c b/lib/pdu.c index bcaf570..c56e91e 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -15,11 +15,16 @@ along with this program; if not, see . */ +#if defined(WIN32) +#include +#else +#include +#include +#endif + #include #include -#include #include -#include #include "iscsi.h" #include "iscsi-private.h" #include "scsi-lowlevel.h" diff --git a/lib/scsi-command.c b/lib/scsi-command.c index 8cf023d..7e96ac4 100644 --- a/lib/scsi-command.c +++ b/lib/scsi-command.c @@ -15,10 +15,15 @@ along with this program; if not, see . */ +#if defined(WIN32) +#include +#else +#include +#endif + #include #include #include -#include #include "iscsi.h" #include "iscsi-private.h" #include "scsi-lowlevel.h" diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index c9460f4..2450849 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -22,15 +22,22 @@ * 4, marshall a real structure into a data-out blob */ +#if defined(WIN32) +#include +#else +#include +#include +#endif + #include #include #include #include -#include #include -#include -#include "scsi-lowlevel.h" #include "slist.h" +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-private.h" void diff --git a/lib/socket.c b/lib/socket.c index fe957a3..eafee0a 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -14,31 +14,42 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ -#include "config.h" -#include -#include -#include +#if defined(WIN32) +#include +#include +#define ioctl ioctlsocket +#define close closesocket +#else +#include "config.h" #include -#include -#include +#include +#include #include #include #include #include #include #include -#include -#include +#endif + +#include +#include +#include +#include +#include #include "iscsi.h" #include "iscsi-private.h" #include "slist.h" static void set_nonblocking(int fd) { +#if defined(WIN32) +#else unsigned v; v = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, v | O_NONBLOCK); +#endif } int @@ -167,6 +178,7 @@ iscsi_disconnect(struct iscsi_context *iscsi) } close(iscsi->fd); + iscsi->fd = -1; iscsi->is_connected = 0; @@ -244,7 +256,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi) if (socket_count < count) { count = socket_count; } - count = read(iscsi->fd, &in->hdr[in->hdr_pos], count); + count = recv(iscsi->fd, &in->hdr[in->hdr_pos], count, 0); if (count < 0) { if (errno == EINTR) { return 0; @@ -292,7 +304,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi) buf = &in->data[in->data_pos]; } - count = read(iscsi->fd, buf, count); + count = recv(iscsi->fd, buf, count, 0); if (count < 0) { if (errno == EINTR) { return 0; @@ -346,10 +358,11 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) total = iscsi->outqueue->outdata.size; total = (total + 3) & 0xfffffffc; - count = write(iscsi->fd, + count = send(iscsi->fd, iscsi->outqueue->outdata.data + iscsi->outqueue->written, - total - iscsi->outqueue->written); + total - iscsi->outqueue->written, + 0); if (count == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return 0; @@ -524,3 +537,34 @@ int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, in } #endif +#if defined(WIN32) +int poll(struct pollfd *fds, int nfsd, int timeout) +{ + fd_set rfds, wfds, efds; + int ret; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + if (fds->events & POLLIN) { + FD_SET(fds->fd, &rfds); + } + if (fds->events & POLLOUT) { + FD_SET(fds->fd, &wfds); + } + FD_SET(fds->fd, &efds); + select(fds->fd + 1, &rfds, &wfds, &efds, NULL); + fds->revents = 0; + if (FD_ISSET(fds->fd, &rfds)) { + fds->revents |= POLLIN; + } + if (FD_ISSET(fds->fd, &wfds)) { + fds->revents |= POLLOUT; + } + if (FD_ISSET(fds->fd, &efds)) { + fds->revents |= POLLHUP; + } + return 1; +} +#endif + diff --git a/lib/sync.c b/lib/sync.c index b3fabbe..07b0f5c 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -15,10 +15,15 @@ along with this program; if not, see . */ +#if defined(WIN32) +#include +#else +#include +#endif + #include #include #include -#include #include "iscsi.h" #include "iscsi-private.h" #include "scsi-lowlevel.h" diff --git a/lib/task_mgmt.c b/lib/task_mgmt.c index d3be124..34f86d1 100644 --- a/lib/task_mgmt.c +++ b/lib/task_mgmt.c @@ -15,8 +15,12 @@ along with this program; if not, see . */ -#include +#if defined(WIN32) +#else #include +#endif + +#include #include "iscsi.h" #include "iscsi-private.h" #include "scsi-lowlevel.h" diff --git a/win32/vsbuild.bat b/win32/vsbuild.bat new file mode 100644 index 0000000..7d1b818 --- /dev/null +++ b/win32/vsbuild.bat @@ -0,0 +1,42 @@ +rem +rem build script for win32 +rem + + +rem +rem generate core part of library +rem +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\connect.c -Folib\connect.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\crc32c.c -Folib\crc32c.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\discovery.c -Folib\discovery.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\init.c -Folib\init.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\login.c -Folib\login.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\md5.c -Folib\md5.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\nop.c -Folib\nop.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\pdu.c -Folib\pdu.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\scsi-command.c -Folib\scsi-command.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\scsi-lowlevel.c -Folib\scsi-lowlevel.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\socket.c -Folib\socket.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\sync.c -Folib\sync.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\task_mgmt.c -Folib\task_mgmt.obj + + + + +rem +rem create a linklibrary/dll +rem +lib /out:lib\libiscsi.lib /def:lib\libiscsi.def lib\connect.obj lib\crc32c.obj lib\discovery.obj lib\init.obj lib\login.obj lib\md5.obj lib\nop.obj lib\pdu.obj lib\scsi-command.obj lib\scsi-lowlevel.obj lib\socket.obj lib\sync.obj lib\task_mgmt.obj + +link /DLL /out:lib\libiscsi.dll /DEBUG /DEBUGTYPE:cv lib\libiscsi.exp lib\connect.obj lib\crc32c.obj lib\discovery.obj lib\init.obj lib\login.obj lib\md5.obj lib\nop.obj lib\pdu.obj lib\scsi-command.obj lib\scsi-lowlevel.obj lib\socket.obj lib\sync.obj lib\task_mgmt.obj ws2_32.lib + + + + +rem +rem build a test application +rem +cl /I. /Iinclude -Zi -Od -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" examples\iscsiclient.c lib\libiscsi.lib WS2_32.lib kernel32.lib mswsock.lib advapi32.lib wsock32.lib advapi32.lib + + +