-1

I need a program that reads chunks of data from a file. The chunk has a dwData, and dwLength field. The dwLength field is the sizeof dwData, just like strlen is for strings.

The problem in this program is that the readChunk0 isn't able to get the dwLength value initialized from the readChunk. The dwLength value is OK in readChunk as cvar.mbsz message displays it correctly (messagebox for a string).

Why am I not able to read dwLength in the test function? Why does dwData gets passed in all right, but not dwLength.

//////////////////////////////////////////////////////////////
//  read contents of a chunk in dwData
//  and dwLength value in a hex file
//
//////////////////////////////////////////////////////////////
DWORD readChunk(DWORD dwData, DWORD dwLength, TCHAR ccSymbol[6]){
    HWND hWnd=cvar.get_hwnd();
    STRCK strform;//readChunk
    strform.cksize=sizeof(STRCK);
    //  strform.ccSymbol=
    //  strform.ckmaxsize=200;
    //  strform.nextck=0x4;

    //open file in HMMIO mode
    //filename is a common one
    cchmmio=mmioOpen("vocer.hex", NULL, MMIO_READ|MMIO_DENYNONE);
    if (cchmmio==NULL){
        MessageBox(hWnd, "eroare 1 mmioOpen", "titlu", 0);
        return 1;
    };

    MMCKINFO lpckParent={0,0,mmioFOURCC('W','A','V','E'),0,0};
    lpckParent.fccType=mmioFOURCC('W','A','V','E');
    lpckParent.cksize=sizeof(MMCKINFO)+sizeof(STRCK);
    HRESULT hr=mmioDescend(cchmmio, (LPMMCKINFO)&lpckParent, NULL, MMIO_FINDCHUNK);
    if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){//&(hr!=MMIOERR_CHUNKNOTFOUND)){
        MessageBox(hWnd, "eroare 2", "titlu", 0);
        return 2;
    };
    if (hr==MMIOERR_CHUNKNOTFOUND){
        MessageBox(hWnd, "eroare 3 WAVE CHUNKNOTFOUND", "titlu", 0);
        return 3;
    };

    MMCKINFO mmckinfo;
    mmckinfo.ckid=mmioStringToFOURCC(ccSymbol, 0);
    //if you find the symbol, read dwData chunk;
    hr=mmioDescend(cchmmio, &mmckinfo, &lpckParent, MMIO_FINDCHUNK);
    if (hr==MMIOERR_CHUNKNOTFOUND){
        MessageBox(hWnd, "4) eroare fatala. ccSymbol not found", "titlu", 0);
        return 4;
    };

    if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
        MessageBox(hWnd, "eroare 5", "titlu", 0);
        return 5;
    }

    dwLength=(DWORD*)mmckinfo.cksize;
//  memcpy(&dwLength, &mmckinfo.cksize, 2);

    hr=mmioRead(cchmmio, (LPSTR)&dwData, (LONG)dwLength);
    if (hr!=(LONG)dwLength){
        MessageBox(hWnd, "eroare 6 mmioRead ccSymbol", "titlu", 0);
        return 6;
    };

    hr=mmioClose(cchmmio, 0);
    if (hr!=MMSYSERR_NOERROR){
        MessageBox(hWnd, "eroare 9 mmioClose", "titlu", 0);
        return 9;
    };

    //ok
    //  cvar.mbsz((LPSTR)dwData, "titlu", 0);//display dwData contents
    //  cvar.mbsz("strlen(szData):", "titlu", strlen((LPSTR)dwData));//display szData value
    cvar.mbsz("(DWORD)dwLength:", "titlu", (DWORD)dwLength);//display length read

    return 0;
}

// Test Function///////////////////////////////////////
//    open vocer.hex file
//    read a ccSymbol chunk and return the
//    dwData and dwLength values
//
void readChunk0(void){
    HWND hWnd=cvar.get_hwnd();
    DWORD dwData=(DWORD)calloc(200, sizeof(DWORD));
    DWORD dwLength=2;
    TCHAR cc[6]="x002";

    HRESULT    hr=readChunk((DWORD*)&dwData, (DWORD*)&dwLength, cc);
    if (hr){
        cvar.mbsz("eroare la revenirea din readChunk:", "titlu", hr);
        return;
    };
    //result is read in dwData
    //and has dwLength length

    //display the length of the message: dwLength (2 methods)
    //and contents of the dwData buffer
    TCHAR sztemp[256];
    sprintf(sztemp, "%d", dwLength);
    MessageBox(hWnd, sztemp, "titlu", 0);
    cvar.mbsz("(DWORD)dwlength:", "titlu", (DWORD)dwLength);
    MessageBox(hWnd, (LPSTR)dwData, "titlu:", 0);
}

EDIT

Thank you Diegos, for your suggestions that are quick and good. I put it together and let you know.

Let me write it down what I understand so far.

//////////////////////////////////////////////////////////////
//  read contents of a iData chunk and iLength value
//  in vocer.hex RIFF file
//
//////////////////////////////////////////////////////////////
DWORD readChunk(int* iData, int* iLength, LPSTR ccSymbol){
HWND hWnd=cvar.get_hwnd();

    if (!PathFileExists(szName0))
        strcpy(szName0, "vocer.hex");

    cchmmio=mmioOpen(szName0, NULL, MMIO_READ|MMIO_DENYNONE);

MMCKINFO lpckParent={0};
lpckParent.fccType=mmioFOURCC('W','A','V','E');
HRESULT hr=mmioDescend(cchmmio, (LPMMCKINFO)&lpckParent, NULL, MMIO_FINDCHUNK);
    if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
        MessageBox(hWnd, "eroare 2", "titlu", 0);
        return 2;
    };
    if (hr==MMIOERR_CHUNKNOTFOUND){
        MessageBox(hWnd, "eroare 3 WAVE CHUNKNOTFOUND", "titlu", 0);
        return 3;
    };

MMCKINFO mmckinfo={0};
    mmckinfo.ckid=mmioStringToFOURCC(ccSymbol, 0);
//daca ai gasit symbolul, citeste chunkul dwData;
    hr=mmioDescend(cchmmio, &mmckinfo, &lpckParent, MMIO_FINDCHUNK);
    if (hr==MMIOERR_CHUNKNOTFOUND){
        MessageBox(hWnd, "eroare 4. ccSymbol not found", "titlu", 0);
        return 4;
    };

    if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
        MessageBox(hWnd, "eroare 5", "titlu", 0);
        return 5;
    };

//  memcpy((int*)iLength, (long*)mmckinfo.cksize, 2);
    iLength[0]=mmckinfo.cksize;

TCHAR sztemp2[256];
TCHAR* sztemp=(TCHAR*)calloc(iLength[0]+1, sizeof(TCHAR));
    hr=mmioRead(cchmmio, (LPSTR)sztemp, (long)iLength[0]);
    sprintf(sztemp2, "iData:%s\nmmioRead:%d", (LPSTR)sztemp, hr);
    MessageBox(hWnd, (LPSTR)sztemp2, "titlu", 0);
    if (hr!=iLength[0]){
        cvar.mbsz("valoare dwLength:", "titlu", (long)iLength[0]);
        MessageBox(hWnd, "eroare 6 mmioRead ccSymbol", "titlu", 0);
        return 6;
    };

    for(int i=0; i<iLength[0]; i++)
        iData[i]=sztemp[i];
//      memcpy(&iData[i], &sztemp[i], 1);

    hr=mmioClose(cchmmio, 0);

    return 0;
}


//Functie Test//////////////////////////////////////////
//  open vocer.hex file
//  read ccSymbol chunk and return
//  dwData of dwLength
//
//////////////////////////////////////////////////////////////
void readChunk00(void){
HWND hWnd=cvar.get_hwnd();
int* iLength=(int*)calloc(1, sizeof(int));
int* iData=(int*)calloc(200, sizeof(int));
TCHAR ccSymbol[6]="0x02";
TCHAR sztemp[200];//=(TCHAR*)calloc(iLength[0]+2, sizeof(TCHAR));

HRESULT hr=readChunk((int*)iData, (int*)iLength, ccSymbol);

    wsprintf(sztemp, "dwLength:%d\niData:%s", iLength[0], (LPSTR)&iData[0]);
    MessageBox(hWnd, (LPSTR)sztemp, "titlu", 0);

    strcpy(sztemp, "");
    MessageBox(hWnd, "inainte de for", "titlu", 0);
    for(int i=0; i<iLength[0]; i++){
//      strcat(sztemp,(LPSTR)&iData[i]);
        sztemp[i]=(TCHAR)&iData[i];
    };

TCHAR* sztemp2=(TCHAR*)calloc(iLength[0]+2, sizeof(TCHAR));
    sprintf(sztemp2, "dwLength:%d\niData:%s", iLength[0], (LPSTR)sztemp);
//  sprintf(sztemp, "dwLength:%d\niData[1]:%d", iLength[0], iData[1]);
    MessageBox(hWnd, (LPSTR)sztemp2, "titlu", 0);
}


//Functie Test///////////////////////////////////////
//  deschide fisierul voce.hex
//  citeste un chunk ccSymbol si returneaza
//  dwData de dimensiune dwLength
//  metoda cu pointer
void readChunk0(void){
HWND hWnd=cvar.get_hwnd();
LPSTR ccSymbol="0x02";
int* dwLength=(int*)calloc(1, sizeof(int));

HGLOBAL hData=GlobalAlloc(GHND, (int)dwLength);
    if (hData==0){
        cvar.mbsz("eroare la GlobalAlloc:", "titlu", GetLastError());
        return;
    };

int* iData=(int*)GlobalLock(hData);
    if (iData==0){
        cvar.mbsz("eroare la GlobalLock:", "titlu", GetLastError());
        return;
    };

HRESULT hr=readChunk((int*)iData, (int*)dwLength, ccSymbol);
    if (hr){
        cvar.mbsz("eroare la revenirea din readChunk:", "titlu", hr);
        return;
    };

    hr=GlobalUnlock(hData);
    if (hr!=0){
        cvar.mbsz("eroare la GlobalUnlock:", "titlu", GetLastError());
        return;
    };

TCHAR* sztemp=(TCHAR*)calloc(dwLength[0]+2, sizeof(TCHAR));
    for(int i=0; i<dwLength[0]; i++)
        sztemp[i]=iData[i];

    strcat(sztemp, "\0");
    MessageBox(hWnd, (LPSTR)sztemp, "titlu", 0);
    cvar.mbsz("(DWORD)dwLength:", "titlu", dwLength[0]);

}

I managed to make it run eventually. Pls guide the next time, because the calloc-function isn’t implemented the same way as GlobalAlloc by the OS (WINDOWS XP). I wrote two functions that have same result, pls correct me if I’m wrong. Function test readChunk00 is done with calloc which cannot read modifications of the first argument dwLength[0] done by the main function in readChunk.

Function readChunk0 is the test function built for the same purpose as readChunk00 but now it uses GlobalAlloc & family functions, which in my opinion are better interpreted by the OS.

By your opinion, is it true that calloc’s first parameter (dwLength[0]) isn’t initialising well by calling hr=readChunk function? This topic wasn't a duplicate. Thank you for your time:)

  • 1
    Your title, your question, your code, and your tags seem not to be related to each other. Please edit your question (?) and clean up. – Jongware Jan 06 '15 at 16:42
  • To read a chunk of data, use `std::istream::read()`. – Thomas Matthews Jan 06 '15 at 16:55
  • 3
    Please tag your question either `[c]` or `[c++]`, but not both. They are not the same thing. What does the tag `[voice-recording]` have to do with reading from a file? – abelenky Jan 06 '15 at 17:06
  • No need to cast here: `(long*)&dwLength`. `&dwLength` will do, as `dwLength` is defined to be a `long`. – alk Jan 10 '15 at 11:22

1 Answers1

2

You need to pass a pointer to dwLength to readChunk and dereference it inside the function if you want the value seen by the caller to be modified.

Also, given the initialization of dwData, it's data type should be DWORD*.


EDIT to catch up with new information.

There are still some problems with your new aproach. Here are some fragments of code I hope you can put together.

This is how you should declare your readChunk function:

DWORD readChunk(DWORD* dwData, DWORD* dwLength, TCHAR ccSymbol[6])

And inside the function this is how you set the value pointed to by dwLength:

*dwLength = mmckinfo.cksize;

In your test function, this is how you declare dwData:

DWORD* dwData = calloc(200, sizeof(DWORD));

and this is how you declare dwLength:

DWORD dwLength;

finally this is how you pass all the data to readChunk:

HRESULT hr = readChunk(dwData, &dwLength, cc);

You really need to become acquainted with how pointers work and how parameters are passed by-value or through the indirection of a pointer in C.

Diego
  • 1,789
  • 10
  • 19