#include #include // Assuming a call is already active and the message LINE_CALLINFO was // received with dwParam1 set to LINECALLINFOSTATE_CALLERID, the // following code will obtain and print out the CallerID information. // The code actively demonstrates the use of the dwTotalSize field // in the variable sized structure LINECALLINFO by initially setting // the size of the structure to simply sizeof(LINECALLINFO) void PrintCallerID(HCALL hCall) { LINECALLINFO *ci; size_t ci_size = sizeof(LINECALLINFO); DWORD result; BOOL done = FALSE; char *p; char szData[80]; // Call lineGetCallInfo to obtain the CallerID information. If TAPI // tells us that the structure is too small, either via the // LINEERR_STRUCTURETOOSMALL error or by indicating that the needed // size of the structure is larger than the total size of the // structure then allocate a new structure and call lineGetCallInfo // again. while (!done) { ci = (LINECALLINFO *)calloc(ci_size, 1); if (ci == NULL) { printf("out of memory\n"); return; } ci->dwTotalSize = ci_size; result = lineGetCallInfo(hCall, ci); if ((result < 0) && (result != LINEERR_STRUCTURETOOSMALL)) { printf("TAPI error 0x%08lx calling lineGetCallInfo\n"); free(ci); return; } done = ((result == 0) && (ci->dwNeededSize <= ci->dwTotalSize)); if (!done) { ci_size = ci->dwNeededSize; free (ci); } }; // while (!done) // Now that we have a full LINECALLINFO structure, obtain the // CallerID information. This is done in multiple steps here // in order to make it simple to understand. This code could // easily be compacted to make it more efficient. // Rather than use a switch statement, check to see if each // individual flag is set. Most of the time only one flag // should be set, but you never know what a TSP might send up. if (ci->dwCallerIDFlags & LINECALLPARTYID_BLOCKED) printf("CallerID is Blocked\n"); if (ci->dwCallerIDFlags & LINECALLPARTYID_UNKNOWN) printf("CallerID is Unknown\n"); if (ci->dwCallerIDFlags & LINECALLPARTYID_UNAVAIL) printf("CallerID is Unavailable\n"); if (ci->dwCallerIDFlags & LINECALLPARTYID_NAME) { p = (char *)ci + ci->dwCallerIDNameOffset; // For string data TAPI will nul-terminate the string, // so technically all this isn't necessary, a simple // strcpy will actually do. But this way shows the use // of the Size field as well as the Offset field. memset(szData, 0, sizeof(szData)); strncpy(szData, p, ci->dwCallerIDNameSize); printf("CallerID Name: %s\n", szData); } if (ci->dwCallerIDFlags & (LINECALLPARTYID_ADDRESS | LINECALLPARTYID_PARTIAL)) { p = (char *)ci + ci->dwCallerIDOffset; memset(szData, 0, sizeof(szData)); strncpy(szData, p, ci->dwCallerIDSize); printf("CallerID : %s\n", szData); } free (ci); }