Figure 1: Dynamic sizing example

LONG CRemoteConnect::mylineGetID()
{
    CommID FAR *cid;
    VARSTRING  *vs;
    LONG lrc;
    DWORD dwSize;
    m_TapiStruct.bGotcommhandle = FALSE;

    // allocate memory for structure
    vs = (VARSTRING *)
         HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
             sizeof(VARSTRING));

    // set structure size
    vs->dwTotalSize = sizeof(VARSTRING);

    // repeat until call satisfied or return on error
    do {

       // get information into structure
       lrc = lineGetID(m_TapiStruct.hLine, 0L, NULL,
                 LINECALLSELECT_LINE, vs, "comm/datamodem");

       // bomb out if error
       if (lrc)  {
          HeapFree(GetProcessHeap(),0,vs);
          return -1;
       }

       // reallocate and try again
       if (vs->dwTotalSize < vs->dwNeededSize) {
          dwSize = vs->dwNeededSize;
          HeapFree(GetProcessHeap(),0,vs);
          vs = (VARSTRING *)
               HeapAlloc(GetProcessHeap(),
                   HEAP_ZERO_MEMORY, dwSize);
          vs->dwTotalSize = dwSize;
          continue;
       } /* end if (need more space) */
       break; /* success  */
    } while (TRUE);

    // copy modem handle and modem name from structure
    cid = (CommID FAR *) ((LPSTR)vs + vs->dwStringOffset);
    lstrcpy (m_TapiStruct.szModemName, &cid->szDeviceName[0]);

    // save modem handle
    m_TapiStruct.hComm = m_hPort = cid->hComm;

    // done with structure; free it
    HeapFree(GetProcessHeap(),0,vs);

    // set flag to indicate modem handle has been retrieved
    m_TapiStruct.bGotcommhandle = TRUE;
    return 0;
} /* end function (mylineGetID) */