Exemple #1
0
XN_C_API XnStatus xnNodeQuerySetSupportedMinUserPositions(XnNodeQuery* pQuery, const XnUInt32 nCount)
{
	XN_VALIDATE_INPUT_PTR(pQuery);
	pQuery->nMinUserPositions = nCount;
	return (XN_STATUS_OK);
}
XnStatus XnDeviceBase::DestroyStreamData(XnStreamData** ppStreamData)
{
	XN_VALIDATE_INPUT_PTR(ppStreamData);

	return XnStreamDataDestroy(ppStreamData);
}
XnStatus XnDeviceBase::UnregisterFromNewStreamData(XnCallbackHandle hCallback)
{
	XN_VALIDATE_INPUT_PTR(hCallback);

	return m_OnNewStreamDataEvent.Unregister(hCallback);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(UnregisterFromPropertyChange)(const XnDeviceHandle DeviceHandle, const XnChar* Module, const XnChar* PropertyName, XnCallbackHandle hCallback)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.UnregisterFromPropertyChange(pHandle->ActualDevice, Module, PropertyName, hCallback);
}
XnStatus XnDeviceBase::RegisterToStreamsChange(XnDeviceOnStreamsChangedEventHandler Handler, void* pCookie, XnCallbackHandle* phCallback)
{
	XN_VALIDATE_INPUT_PTR(Handler);

	return m_OnStreamsChangeEvent.Register((StreamCollectionChangedEvent::HandlerPtr)Handler, pCookie, phCallback);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(LoadConfigFromFile)(const XnDeviceHandle DeviceHandle, const XnChar* csINIFilePath, const XnChar* csSectionName)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.LoadConfigFromFile(pHandle->ActualDevice, csINIFilePath, csSectionName);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(GetAllProperties)(const XnDeviceHandle DeviceHandle, XnPropertySet* pPropertySet, XnBool bNoStreams /* = FALSE */, const XnChar* strModule /* = NULL */)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.GetAllProperties(pHandle->ActualDevice, pPropertySet, bNoStreams, strModule);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(GetStreamNames)(const XnDeviceHandle DeviceHandle, const XnChar** pstrNames, XnUInt32* pnNamesCount)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.GetStreamNames(pHandle->ActualDevice, pstrNames, pnNamesCount);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(RegisterToNewStreamData)(const XnDeviceHandle DeviceHandle, XnDeviceOnNewStreamDataEventHandler Handler, void* pCookie, XnCallbackHandle& hCallback)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.RegisterToNewStreamData(pHandle->ActualDevice, Handler, pCookie, hCallback);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(OpenStream)(const XnDeviceHandle DeviceHandle, const XnChar* StreamName)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.OpenStream(pHandle->ActualDevice, StreamName);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(CloseAllStreams)(const XnDeviceHandle DeviceHandle)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.CloseAllStreams(pHandle->ActualDevice);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(CreateStream)(const XnDeviceHandle DeviceHandle, const XnChar* StreamType, const XnChar* StreamName, const XnPropertySet* pInitialValues)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.CreateStream(pHandle->ActualDevice, StreamType, StreamName, pInitialValues);
}
Exemple #13
0
XN_DDK_API XnStatus XnShiftToDepthUpdate(XnShiftToDepthTables* pShiftToDepth, const XnShiftToDepthConfig* pConfig)
{
	XN_VALIDATE_INPUT_PTR(pShiftToDepth);
	XN_VALIDATE_INPUT_PTR(pConfig);

	// check max shift wasn't changed (if so, memory should be re-allocated)
	if (pConfig->nDeviceMaxShiftValue > pShiftToDepth->nShiftsCount)
		return XN_STATUS_DEVICE_INVALID_MAX_SHIFT;

	// check max depth wasn't changed (if so, memory should be re-allocated)
	if (pConfig->nDeviceMaxDepthValue > pShiftToDepth->nDepthsCount)
		return XN_STATUS_DEVICE_INVALID_MAX_DEPTH;

	XnUInt32 nIndex = 0;
	XnInt16  nShiftValue = 0;
	XnDouble dFixedRefX = 0;
	XnDouble dMetric = 0;
	XnDouble dDepth = 0;
	XnDouble dPlanePixelSize = pConfig->fZeroPlanePixelSize;
	XnDouble dPlaneDsr = pConfig->nZeroPlaneDistance;
	XnDouble dPlaneDcl = pConfig->fEmitterDCmosDistance;
	XnInt32 nConstShift = pConfig->nParamCoeff * pConfig->nConstShift;

	dPlanePixelSize *= pConfig->nPixelSizeFactor;
	nConstShift /= pConfig->nPixelSizeFactor;

	XnDepthPixel* pShiftToDepthTable = pShiftToDepth->pShiftToDepthTable;
	XnUInt16* pDepthToShiftTable = pShiftToDepth->pDepthToShiftTable;

	xnOSMemSet(pShiftToDepthTable, 0, pShiftToDepth->nShiftsCount * sizeof(XnDepthPixel));
	xnOSMemSet(pDepthToShiftTable, 0, pShiftToDepth->nDepthsCount * sizeof(XnUInt16));

	XnUInt16 nLastDepth = 0;
	XnUInt16 nLastIndex = 0;

	for (nIndex = 1; nIndex < pConfig->nDeviceMaxShiftValue; nIndex++)
	{
		nShiftValue = nIndex;

		dFixedRefX = (XnDouble)(nShiftValue - nConstShift) / (XnDouble)pConfig->nParamCoeff;
		dFixedRefX -= 0.375;
		dMetric = dFixedRefX * dPlanePixelSize;
		dDepth = pConfig->nShiftScale * ((dMetric * dPlaneDsr / (dPlaneDcl - dMetric)) + dPlaneDsr);

		// check cut-offs
		if ((dDepth > pConfig->nDepthMinCutOff) && (dDepth < pConfig->nDepthMaxCutOff))
		{
			pShiftToDepthTable[nIndex] = (XnUInt16)dDepth;

			for (XnUInt16 i = nLastDepth; i < dDepth; i++)
				pDepthToShiftTable[i] = nLastIndex;

			nLastIndex = nIndex;
			nLastDepth = (XnUInt16)dDepth;
		}
	}

	for (XnUInt16 i = nLastDepth; i <= pConfig->nDeviceMaxDepthValue; i++)
		pDepthToShiftTable[i] = nLastIndex;

	return XN_STATUS_OK;
}
Exemple #14
0
XN_C_API XnStatus XN_C_DECL xnNodeQuerySetNonExistingNodeOnly(XnNodeQuery* pQuery, XnBool bNonExistingNode)
{
	XN_VALIDATE_INPUT_PTR(pQuery);
	pQuery->bNonExistingNodeOnly = bNonExistingNode;
	return (XN_STATUS_OK);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(SetStringProperty)(const XnDeviceHandle DeviceHandle, const XnChar* ModuleName, const XnChar* PropertyName, const XnChar* csValue)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.SetStringProperty(pHandle->ActualDevice, ModuleName, PropertyName, csValue);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(UnregisterFromNewStreamData)(const XnDeviceHandle DeviceHandle, XnCallbackHandle hCallback)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.UnregisterFromNewStreamData(pHandle->ActualDevice, hCallback);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(GetGeneralProperty)(const XnDeviceHandle DeviceHandle, const XnChar* ModuleName, const XnChar* PropertyName, const XnGeneralBuffer* pValue)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.GetGeneralProperty(pHandle->ActualDevice, ModuleName, PropertyName, pValue);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(IsNewDataAvailable)(const XnDeviceHandle DeviceHandle, const XnChar* StreamName, XnBool* pbNewDataAvailable, XnUInt64* pnTimestamp)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.IsNewDataAvailable(pHandle->ActualDevice, StreamName, pbNewDataAvailable, pnTimestamp);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(BatchConfig)(const XnDeviceHandle DeviceHandle, const XnPropertySet* pChangeSet)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.BatchConfig(pHandle->ActualDevice, pChangeSet);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(Write)(const XnDeviceHandle DeviceHandle, XnStreamDataSet* pStreamOutputSet)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.Write(pHandle->ActualDevice, pStreamOutputSet);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(RegisterToPropertyChange)(const XnDeviceHandle DeviceHandle, const XnChar* Module, const XnChar* PropertyName, XnDeviceOnPropertyChangedEventHandler Handler, void* pCookie, XnCallbackHandle& hCallback)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.RegisterToPropertyChange(pHandle->ActualDevice, Module, PropertyName, Handler, pCookie, hCallback);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(Seek)(const XnDeviceHandle DeviceHandle, XnUInt64 nTimestamp)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.Seek(pHandle->ActualDevice, nTimestamp);
}
static XnStatus OpenSharedMemoryImpl(const XnChar* strName, XnUInt32 nAccessFlags, XN_SHARED_MEMORY_HANDLE* phSharedMem, XnUInt32 nSize)
{
	XnStatus nRetVal = XN_STATUS_OK;

	XN_VALIDATE_INPUT_PTR(strName);
	XN_VALIDATE_OUTPUT_PTR(phSharedMem);
	
	// if (nSize) is a number - create, otherwise - open
	XnBool bCreate = (nSize != 0);

	// convert to local OS types
	int prot = 0;
	int nCreateFlags = 0;
	int nMode = 0;

	nRetVal = AccessFlagsToMMapProt(nAccessFlags, &prot);
	XN_IS_STATUS_OK(nRetVal);

	nRetVal = AccessFlagsToOpenFlags(nAccessFlags, &nCreateFlags);
	XN_IS_STATUS_OK(nRetVal);

	// allocate handle
	XnOSSharedMemory* pHandle;
	XN_VALIDATE_CALLOC(pHandle, XnOSSharedMemory, 1);

	pHandle->bCreate = bCreate;

	NameToFileName(strName, pHandle->strFileName);

	if (bCreate)
	{
		nCreateFlags |= O_CREAT;
		nMode |= S_IRWXU | S_IRWXG | S_IRWXO;
	}

	// open file
	int fd = shm_open(pHandle->strFileName, nCreateFlags, nMode);
	if (fd == -1)
	{
		xnOSFree(pHandle);
		XN_LOG_WARNING_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not create file '%s' for shared memory (%d).", pHandle->strFileName, errno);
	}

	if (bCreate)
	{
		// set it to the right size
		if (-1 == ftruncate(fd, nSize))
		{
			close(fd);
			shm_unlink(pHandle->strFileName);
			xnOSFree(pHandle);
			XN_LOG_WARNING_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not seek to position (%d).", pHandle->strFileName, errno);
		}

		pHandle->nSize = nSize;
	}
	else
	{
		// read shared object size
		pHandle->nSize = lseek(fd, 0, SEEK_END);
	}

	// and map it
	pHandle->pAddress = mmap(NULL, pHandle->nSize, prot, MAP_SHARED, fd, 0);
	if (pHandle->pAddress == MAP_FAILED)
	{
		close(fd);
		shm_unlink(pHandle->strFileName);
		xnOSFree(pHandle);
		XN_LOG_WARNING_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not create file mapping object (%d).", errno);
	}
	
	close(fd);

	*phSharedMem = pHandle;

	return (XN_STATUS_OK);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(SeekFrame)(const XnDeviceHandle DeviceHandle, XnUInt32 nFrameID)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.SeekFrame(pHandle->ActualDevice, nFrameID);
}
XnStatus XnDeviceBase::UnregisterFromStreamsChange(XnCallbackHandle hCallback)
{
	XN_VALIDATE_INPUT_PTR(hCallback);

	return m_OnStreamsChangeEvent.Unregister(hCallback);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(DoesPropertyExist)(const XnDeviceHandle DeviceHandle, const XnChar* ModuleName, const XnChar* PropertyName, XnBool* pbDoesExist)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.DoesPropertyExist(pHandle->ActualDevice, ModuleName, PropertyName, pbDoesExist);
}
XnStatus XnDeviceBase::RegisterToNewStreamData(XnDeviceOnNewStreamDataEventHandler Handler, void* pCookie, XnCallbackHandle* phCallback)
{
	XN_VALIDATE_INPUT_PTR(Handler);

	return m_OnNewStreamDataEvent.Register(Handler, pCookie, phCallback);
}
XN_DDK_API XnStatus XN_DEVICE_PROXY_PROTO(GetPropertyType)(const XnDeviceHandle DeviceHandle, const XnChar* ModuleName, const XnChar* PropertyName, XnPropertyType* pnType)
{
	XN_VALIDATE_INPUT_PTR(DeviceHandle);
	XnDeviceProxyDeviceHandle* pHandle = (XnDeviceProxyDeviceHandle*)DeviceHandle;
	return pHandle->pDesc->Interface.GetPropertyType(pHandle->ActualDevice, ModuleName, PropertyName, pnType);
}
Exemple #29
0
XN_C_API XnStatus xnOSConnectSocket(XN_SOCKET_HANDLE Socket, XnUInt32 nMillisecsTimeout)
{
	// Local function variables
	XnInt32 nRetVal = 0;
	sockaddr SocketAddress;
	fd_set fdWriteHandles;
	fd_set fdExceptHandles;
	struct timeval selectTimeOut;
	struct timeval* pTimeout = xnOSMillisecsToTimeVal(nMillisecsTimeout, &selectTimeOut);

	// Validate the input/output pointers (to make sure none of them is NULL)
	XN_VALIDATE_INPUT_PTR(Socket);

	// Make sure the actual socket handle isn't NULL
	XN_RET_IF_NULL(Socket->Socket, XN_STATUS_OS_INVALID_SOCKET);

	// Connect to the socket and make sure it succeeded
	if (sizeof(SocketAddress) != sizeof(Socket->SocketAddress))
	{
		return(XN_STATUS_OS_NETWORK_SOCKET_CONNECT_FAILED);
	}

	xnOSMemCopy(&SocketAddress, &Socket->SocketAddress, sizeof(SocketAddress));

	// if timeout is XN_SOCKET_DEFAULT_TIMEOUT, leave the socket as a blocking one
	if (nMillisecsTimeout != XN_SOCKET_DEFAULT_TIMEOUT)
	{
		// Make the socket non-blocking temporarily
		u_long nNonBlockingSocket = 1;
		if (ioctlsocket(Socket->Socket, FIONBIO, &nNonBlockingSocket) != 0)
		{
			XN_LOG_ERROR_RETURN(XN_STATUS_OS_NETWORK_SOCKET_CONNECT_FAILED, XN_MASK_OS, "ioctlsocket() failed with error %d", WSAGetLastError());
			return(XN_STATUS_OS_NETWORK_SOCKET_CONNECT_FAILED);
		}
	}

	nRetVal = connect(Socket->Socket, &SocketAddress, sizeof(SocketAddress));
	if ((nRetVal == SOCKET_ERROR) && (WSAGetLastError() != WSAEWOULDBLOCK))
	{
		xnLogError(XN_MASK_OS, "connect() failed with winsock error %d", WSAGetLastError());
		return(XN_STATUS_OS_NETWORK_SOCKET_CONNECT_FAILED);
	}

	if (nMillisecsTimeout != XN_SOCKET_DEFAULT_TIMEOUT)
	{
		FD_ZERO(&fdWriteHandles);
		FD_SET(Socket->Socket, &fdWriteHandles);
		FD_ZERO(&fdExceptHandles);
		FD_SET(Socket->Socket, &fdExceptHandles);
		nRetVal = select(1 /* ignored */, NULL, &fdWriteHandles, &fdExceptHandles, pTimeout);

		// in any case, make the socket blocking again before we check select()'s success
		u_long nBlockingSocket = 0;
		ioctlsocket(Socket->Socket, FIONBIO, &nBlockingSocket);

		if (nRetVal == 0)
		{
			return (XN_STATUS_OS_NETWORK_TIMEOUT);
		}
		else if (nRetVal == SOCKET_ERROR)
		{
			XN_LOG_ERROR_RETURN(XN_STATUS_OS_NETWORK_SOCKET_CONNECT_FAILED, XN_MASK_OS, "select() returned WinSock error: %d", WSAGetLastError());
		}
		else
		{
			// select returned due to socket state change. Check if an error occurred or everything is OK.
			if (FD_ISSET(Socket->Socket, &fdExceptHandles))
			{
				XnUInt32 nLastError = 0;
				XnInt32 nLastErrorSize = sizeof(nLastError);
				getsockopt(Socket->Socket, SOL_SOCKET, SO_ERROR, (char*)&nLastError, &nLastErrorSize);
				XN_LOG_ERROR_RETURN(XN_STATUS_OS_NETWORK_SOCKET_CONNECT_FAILED, XN_MASK_OS, "Connect failed with error: %u", nLastError);
			}
			// else, it means it's in the writable state, which means connect succeeded.
			XN_ASSERT(FD_ISSET(Socket->Socket, &fdWriteHandles));
		}
	}

	// All is good...
	return (XN_STATUS_OK);
}
Exemple #30
0
XN_DDK_API XnStatus XnPropertySetEnumeratorMoveNext(XnPropertySetEnumerator* pEnumerator, XnBool* pbEnd)
{
	XnStatus nRetVal = XN_STATUS_OK;

	XN_VALIDATE_INPUT_PTR(pEnumerator);
	XN_VALIDATE_OUTPUT_PTR(pbEnd);

	*pbEnd = TRUE;

	if (pEnumerator->strModule[0] != '\0') // single module
	{
		if (pEnumerator->bFirst)
		{
			pEnumerator->bFirst = FALSE;

			// find this module
			nRetVal = pEnumerator->pModules->Find(pEnumerator->strModule, pEnumerator->itModule);
			if (nRetVal == XN_STATUS_NO_MATCH)
			{
				pEnumerator->itModule = pEnumerator->pModules->End();
			}
			XN_IS_STATUS_OK(nRetVal);

			pEnumerator->itProp = pEnumerator->itModule->Value()->Begin();
		}
		else if (pEnumerator->itProp == pEnumerator->itModule->Value()->End())
		{
			return XN_STATUS_ILLEGAL_POSITION;
		}
		else
		{
			// advance prop iterator
			++pEnumerator->itProp;
		}

		*pbEnd = (pEnumerator->itProp == pEnumerator->itModule->Value()->End());
	}
	else // all modules
	{
		if (pEnumerator->bFirst)
		{
			pEnumerator->bFirst = FALSE;

			// search for the first modules that has properties
			pEnumerator->itModule = pEnumerator->pModules->Begin();
			while (pEnumerator->itModule != pEnumerator->pModules->End() && pEnumerator->itModule->Value()->IsEmpty())
			{
				pEnumerator->itModule++;
			}

			// if we found one, take it's first property
			if (pEnumerator->itModule != pEnumerator->pModules->End())
			{
				pEnumerator->itProp = pEnumerator->itModule->Value()->Begin();
				*pbEnd = FALSE;
			}
			else
			{
				*pbEnd = TRUE;
			}
		}
		else if (pEnumerator->itModule == pEnumerator->pModules->End())
		{
			return XN_STATUS_ILLEGAL_POSITION;
		}
		else
		{
			// move to next one
			++pEnumerator->itProp;

			// check if we reached end of module
			if (pEnumerator->itProp == pEnumerator->itModule->Value()->End())
			{
				// move to next module with properties
				do
				{
					pEnumerator->itModule++;
				}
				while (pEnumerator->itModule != pEnumerator->pModules->End() && pEnumerator->itModule->Value()->IsEmpty());

				// if we found one, take it's first property
				if (pEnumerator->itModule != pEnumerator->pModules->End())
				{
					pEnumerator->itProp = pEnumerator->itModule->Value()->Begin();
					*pbEnd = FALSE;
				}
				else
				{
					*pbEnd = TRUE;
				}
			}
			else
			{
				*pbEnd = FALSE;
			}
		}
	}

	return (XN_STATUS_OK);
}