Check-in [0058a3b41b]
Overview
Comment:Added support for CKF_DONT_BLOCK
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wait-for-slot-event
Files: files | file ages | folders
SHA1:0058a3b41b4de5a7e3b7a2e3336b6791e48fe8cb
User & Date: rkeene on 2013-08-18 07:02:27
Other Links: manifest | tags
Context
2013-08-19
03:14
Improved waiting for slot event to allow C_Finalize to terminate any waiting Leaf check-in: d52881feec user: rkeene tags: wait-for-slot-event
2013-08-18
07:02
Added support for CKF_DONT_BLOCK check-in: 0058a3b41b user: rkeene tags: wait-for-slot-event
06:53
First work towards implementing C_WaitForSlotEvent check-in: 4d4946cc1f user: rkeene tags: wait-for-slot-event
Changes

Modified cackey.c from [0817c7d1f8] to [5d076538a2].

  4733   4733   	SCARD_READERSTATE reader_states[(sizeof(cackey_slots) / sizeof(cackey_slots[0])) + 1];
  4734   4734   	SCARDCONTEXT pcsc_handle;
  4735   4735   	LONG scard_getstatchng_ret;
  4736   4736   	LONG scard_est_context_ret;
  4737   4737   	struct cackey_slot *cackey_slot;
  4738   4738   	unsigned int currslot, reader_state_slot;
  4739   4739   	int pcsc_connect_ret;
         4740  +	int slot_changed;
  4740   4741   
  4741   4742   	CACKEY_DEBUG_PRINTF("Called.");
  4742   4743   
  4743   4744   	if (pReserved != NULL) {
  4744   4745   		CACKEY_DEBUG_PRINTF("Error. pReserved is not NULL.");
  4745   4746   
  4746   4747   		return(CKR_ARGUMENTS_BAD);
................................................................................
  4761   4762   	pcsc_connect_ret = cackey_pcsc_connect();
  4762   4763   	if (pcsc_connect_ret != CACKEY_PCSC_S_OK) {
  4763   4764   		CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure");
  4764   4765   
  4765   4766   		return(CKR_GENERAL_ERROR);
  4766   4767   	}
  4767   4768   
  4768         -	if ((flags & CKF_DONT_BLOCK) == CKF_DONT_BLOCK) {
  4769         -		/* XXX TODO */
  4770         -		CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because we were asked to not block", CKR_GENERAL_ERROR);
         4769  +	for (reader_state_slot = currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
         4770  +		if (cackey_slots[currslot].internal) {
         4771  +			continue;
         4772  +		}
  4771   4773   
  4772         -		return(CKR_GENERAL_ERROR);
  4773         -	} else {
  4774         -		for (reader_state_slot = currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
  4775         -			if (cackey_slots[currslot].internal) {
  4776         -				continue;
  4777         -			}
         4774  +		if (cackey_slots[currslot].active == 0) {
         4775  +			continue;
         4776  +		}
  4778   4777   
  4779         -			if (cackey_slots[currslot].active == 0) {
  4780         -				continue;
  4781         -			}
         4778  +		reader_states[reader_state_slot].szReader = cackey_slots[currslot].pcsc_reader;
         4779  +		reader_states[reader_state_slot].pvUserData = &cackey_slots[currslot];
  4782   4780   
  4783         -			reader_states[reader_state_slot].szReader = cackey_slots[currslot].pcsc_reader;
  4784         -			reader_states[reader_state_slot].pvUserData = &cackey_slots[currslot];
  4785         -
         4781  +		if ((flags & CKF_DONT_BLOCK) == CKF_DONT_BLOCK) {
         4782  +			reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE;
         4783  +		} else {
  4786   4784   			reader_states[reader_state_slot].dwCurrentState = cackey_slots[currslot].pcsc_state;
  4787         -
  4788         -			reader_state_slot++;
  4789   4785   		}
  4790   4786   
  4791         -		reader_states[reader_state_slot].szReader = "\\\\?PnP?\\Notification";
  4792         -		reader_states[reader_state_slot].pvUserData = NULL;
  4793         -		reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE;
  4794   4787   		reader_state_slot++;
  4795         -
  4796         -		scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &pcsc_handle);
  4797         -		if (scard_est_context_ret != SCARD_S_SUCCESS) {
  4798         -			CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because SCardEstablishContext failed: %lx", CKR_GENERAL_ERROR, scard_est_context_ret);
  4799         -
  4800         -			return(CKR_GENERAL_ERROR);
  4801         -		}
  4802         -
  4803         -		scard_getstatchng_ret = SCardGetStatusChange(pcsc_handle, INFINITE, reader_states, reader_state_slot);
  4804         -
  4805         -		SCardReleaseContext(pcsc_handle);
  4806         -
  4807         -		if (scard_getstatchng_ret != SCARD_S_SUCCESS) {
  4808         -			CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because SCardGetStatusChange failed: %lx", CKR_GENERAL_ERROR, scard_getstatchng_ret);
  4809         -
  4810         -			return(CKR_GENERAL_ERROR);
  4811         -		}
  4812         -
  4813         -		for (currslot = 0; currslot < reader_state_slot; currslot++) {
  4814         -			CACKEY_DEBUG_PRINTF("[slot = %u] CurrentState = %lx, EventState = %lx",
  4815         -			    currslot,
  4816         -			    reader_states[currslot].dwCurrentState & 0xffff,
  4817         -			    reader_states[currslot].dwEventState & 0xffff
  4818         -			);
  4819         -
         4788  +	}
         4789  +
         4790  +	reader_states[reader_state_slot].szReader = "\\\\?PnP?\\Notification";
         4791  +	reader_states[reader_state_slot].pvUserData = NULL;
         4792  +	reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE;
         4793  +	reader_state_slot++;
         4794  +
         4795  +	scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &pcsc_handle);
         4796  +	if (scard_est_context_ret != SCARD_S_SUCCESS) {
         4797  +		CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because SCardEstablishContext failed: %lx", CKR_GENERAL_ERROR, scard_est_context_ret);
         4798  +
         4799  +		return(CKR_GENERAL_ERROR);
         4800  +	}
         4801  +
         4802  +	scard_getstatchng_ret = SCardGetStatusChange(pcsc_handle, INFINITE, reader_states, reader_state_slot);
         4803  +
         4804  +	SCardReleaseContext(pcsc_handle);
         4805  +
         4806  +	if (scard_getstatchng_ret != SCARD_S_SUCCESS) {
         4807  +		CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because SCardGetStatusChange failed: %lx", CKR_GENERAL_ERROR, scard_getstatchng_ret);
         4808  +
         4809  +		return(CKR_GENERAL_ERROR);
         4810  +	}
         4811  +
         4812  +	for (currslot = 0; currslot < reader_state_slot; currslot++) {
         4813  +		CACKEY_DEBUG_PRINTF("[slot = %u] CurrentState = %lx, EventState = %lx",
         4814  +		    currslot,
         4815  +		    reader_states[currslot].dwCurrentState & 0xffff,
         4816  +		    reader_states[currslot].dwEventState & 0xffff
         4817  +		);
         4818  +
         4819  +		cackey_slot = (struct cackey_slot *) reader_states[currslot].pvUserData;
         4820  +
         4821  +		if (cackey_slot == NULL) {
         4822  +			/* XXX: TODO: Someone plugged in a new slot */
         4823  +			continue;
         4824  +		}
         4825  +
         4826  +		slot_changed = 0;
         4827  +
         4828  +		if ((flags & CKF_DONT_BLOCK) == CKF_DONT_BLOCK) {
         4829  +			if (cackey_slot->pcsc_state != reader_states[currslot].dwEventState) {
         4830  +				slot_changed = 1;
         4831  +			}
         4832  +		} else {
  4820   4833   			if (reader_states[currslot].dwCurrentState != reader_states[currslot].dwEventState) {
  4821         -				cackey_slot = (struct cackey_slot *) reader_states[currslot].pvUserData;
  4822         -
  4823         -				if (cackey_slot == NULL) {
  4824         -					/* XXX: TODO: Someone plugged in a new slot */
  4825         -					continue;
  4826         -				}
  4827         -
  4828         -				CACKEY_DEBUG_PRINTF("Returning slot changed: %u", (unsigned int) cackey_slot->id);
  4829         -
  4830         -				cackey_slot->pcsc_state = reader_states[currslot].dwEventState;
  4831         -				*pSlotID = (CK_SLOT_ID) cackey_slot->id;
  4832         -
  4833         -				CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
  4834         -
  4835         -				return(CKR_OK);
  4836         -			}
  4837         -		}
  4838         -	}
  4839         -
  4840         -	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  4841         -
  4842         -	return(CKR_FUNCTION_NOT_SUPPORTED);
         4834  +				slot_changed = 1;
         4835  +			}
         4836  +		}
         4837  +
         4838  +		if (slot_changed == 0) {
         4839  +			continue;
         4840  +		}
         4841  +
         4842  +		CACKEY_DEBUG_PRINTF("Returning slot changed: %u", (unsigned int) cackey_slot->id);
         4843  +
         4844  +		cackey_slot->pcsc_state = reader_states[currslot].dwEventState;
         4845  +		*pSlotID = (CK_SLOT_ID) cackey_slot->id;
         4846  +
         4847  +		CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
         4848  +
         4849  +		return(CKR_OK);
         4850  +	}
         4851  +
         4852  +	if ((flags & CKF_DONT_BLOCK) != CKF_DONT_BLOCK) {
         4853  +		CACKEY_DEBUG_PRINTF("Returning CKR_NO_EVENT (%i), but asked to block !? BUG ENCOUNTERED.", CKR_NO_EVENT);
         4854  +	} else {
         4855  +		CACKEY_DEBUG_PRINTF("Returning CKR_NO_EVENT (%i)", CKR_NO_EVENT);
         4856  +	}
         4857  +
         4858  +	return(CKR_NO_EVENT);
  4843   4859   }
  4844   4860   
  4845   4861   CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) {
  4846   4862   	CACKEY_DEBUG_PRINTF("Called.");
  4847   4863   
  4848   4864   	if (!cackey_initialized) {
  4849   4865   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");

Modified test.c from [1ccfa3a69d] to [ef0e023dd5].

   226    226   	slots = malloc(sizeof(*slots) * numSlots);
   227    227   
   228    228   	chk_rv = C_GetSlotList(FALSE, slots, &numSlots);
   229    229   	if (chk_rv != CKR_OK) {
   230    230   		return(1);
   231    231   	}
   232    232   
          233  +	/* Test waiting for slot events */
   233    234   	currSlot = 0;
   234    235   	printf("Please insert a card now.\n");
          236  +
          237  +	/* Initially, every slot has changed state (but probably should not) */
          238  +	chk_rv = C_WaitForSlotEvent(0, &currSlot, NULL);
          239  +
          240  +	/* This actually waits */
   235    241   	chk_rv = C_WaitForSlotEvent(0, &currSlot, NULL);
   236    242   	if (chk_rv != CKR_OK) {
   237    243   		printf("Failed to wait for slot event.\n");
   238    244   	}
   239    245   
          246  +	/* This just ensures DONT_BLOCK works */
          247  +	chk_rv = C_WaitForSlotEvent(CKF_DONT_BLOCK, &currSlot, NULL);
          248  +
   240    249   	for (currSlot = 0; currSlot < numSlots; currSlot++) {
   241    250   		printf("  Slot %lu:\n", currSlot);
   242    251   
   243    252   		chk_rv = C_GetSlotInfo(slots[currSlot], &slotInfo);
   244    253   		if (chk_rv != CKR_OK) {
   245    254   			return(1);
   246    255   		}