Пример #1
0
OGRErr OGRSelafinLayer::DeleteField(int iField) {
    CPLDebug("Selafin","DeleteField(%i)",iField);
    if (VSIFSeekL(poHeader->fp,poHeader->getPosition(0),SEEK_SET)!=0) return OGRERR_FAILURE;
    // Change the header to remove the field
    poHeader->nVar--;
    poHeader->setUpdated();
    CPLFree(poHeader->papszVariables[iField]);
    for (long i=iField;i<poHeader->nVar;++i) poHeader->papszVariables[i]=poHeader->papszVariables[i+1];
    poHeader->papszVariables=(char**)CPLRealloc(poHeader->papszVariables,sizeof(char*)*poHeader->nVar);
    poFeatureDefn->DeleteFieldDefn(iField);
    
    // Now comes the real deletion. Since values have to be deleted nearly everywhere in the file and we don't want to store everything in memory to overwrite it, we create a new copy of it where we write the new values
    VSILFILE *fpNew;
    const char *pszTempfile=CPLGenerateTempFilename(0);
    fpNew=VSIFOpenL(pszTempfile,"wb+");
    if( fpNew == NULL ) {
        CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open temporary file %s with write access, %s.",pszTempfile, VSIStrerror( errno ) );
        return OGRERR_FAILURE;
    } 
    if (Selafin::write_header(fpNew,poHeader)==0) {
        VSIFCloseL(fpNew);
        VSIUnlink(pszTempfile);
        return OGRERR_FAILURE;
    }
    long nLen;
    double dfDate;
    double *padfValues;
    for (long i=0;i<poHeader->nSteps;++i) {
        if (Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::read_float(poHeader->fp,dfDate)==0 ||
                Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::write_integer(fpNew,4)==0 ||
                Selafin::write_float(fpNew,dfDate)==0 ||
                Selafin::write_integer(fpNew,4)==0) {
            VSIFCloseL(fpNew);
            VSIUnlink(pszTempfile);
            return OGRERR_FAILURE;
        }
        for (long j=0;j<poHeader->nVar;++j) {
            if (Selafin::read_floatarray(poHeader->fp,&padfValues)==-1) {
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            if (j!=iField) {
                if (Selafin::write_floatarray(fpNew,padfValues,poHeader->nPoints)==0) {
                    CPLFree(padfValues);
                    VSIFCloseL(fpNew);
                    VSIUnlink(pszTempfile);
                    return OGRERR_FAILURE;
                }
            }
            CPLFree(padfValues);   
        }
    }
    MoveOverwrite(poHeader->fp,fpNew);
    VSIUnlink(pszTempfile);
    return OGRERR_NONE;
}
Пример #2
0
OGRErr OGRSelafinLayer::ReorderFields(int *panMap) {
    CPLDebug("Selafin","ReorderFields()");
    if (VSIFSeekL(poHeader->fp,poHeader->getPosition(0),SEEK_SET)!=0) return OGRERR_FAILURE;
    // Change the header according to the map
    char **papszNew=(char**)VSIMalloc2(sizeof(char*),poHeader->nVar);
    for (long i=0;i<poHeader->nVar;++i) papszNew[i]=poHeader->papszVariables[panMap[i]];
    CPLFree(poHeader->papszVariables);
    poHeader->papszVariables=papszNew;
    poFeatureDefn->ReorderFieldDefns(panMap);

    // Now comes the real change.
    VSILFILE *fpNew;
    const char *pszTempfile=CPLGenerateTempFilename(0);
    fpNew=VSIFOpenL(pszTempfile,"wb+");
    if( fpNew == NULL ) {
        CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open temporary file %s with write access, %s.",pszTempfile, VSIStrerror( errno ) );
        return OGRERR_FAILURE;
    } 
    if (Selafin::write_header(fpNew,poHeader)==0) {
        VSIFCloseL(fpNew);
        VSIUnlink(pszTempfile);
        return OGRERR_FAILURE;
    }
    long nLen;
    double dfDate;
    double *padfValues=0;
    for (long i=0;i<poHeader->nSteps;++i) {
        if (Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::read_float(poHeader->fp,dfDate)==0 ||
                Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::write_integer(fpNew,4)==0 ||
                Selafin::write_float(fpNew,dfDate)==0 ||
                Selafin::write_integer(fpNew,4)==0) {
            VSIFCloseL(fpNew);
            VSIUnlink(pszTempfile);
            return OGRERR_FAILURE;
        }
        for (long j=0;j<poHeader->nVar;++j) {
            if (VSIFSeekL(poHeader->fp,poHeader->getPosition(i,-1,panMap[j]),SEEK_SET)!=0 || Selafin::read_floatarray(poHeader->fp,&padfValues)==-1) {
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            if (Selafin::write_floatarray(fpNew,padfValues,poHeader->nPoints)==0) {
                CPLFree(padfValues);
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            CPLFree(padfValues);
        }
    }
    MoveOverwrite(poHeader->fp,fpNew);
    VSIUnlink(pszTempfile);
    return OGRERR_NONE;
}
Пример #3
0
OGRErr OGRSelafinLayer::DeleteFeature(GIntBig nFID) {
    CPLDebug("Selafin","DeleteFeature(" CPL_FRMT_GIB ")",nFID);
    if (VSIFSeekL(poHeader->fp,poHeader->getPosition(0),SEEK_SET)!=0) return OGRERR_FAILURE;
    // Change the header to delete the feature
    if (eType==POINTS) poHeader->removePoint((long)nFID); else {
        // For elements layer, we only delete the element and not the vertices
        poHeader->nElements--;
        for (long i=(long)nFID;i<poHeader->nElements;++i)
            for (long j=0;j<poHeader->nPointsPerElement;++j)
                poHeader->panConnectivity[poHeader->nPointsPerElement*i+j]=poHeader->panConnectivity[poHeader->nPointsPerElement*(i+1)+j];
        poHeader->panConnectivity=(long*)CPLRealloc(poHeader->panConnectivity,sizeof(long)*poHeader->nPointsPerElement*poHeader->nElements);
        poHeader->setUpdated();
    }

    // Now we perform the deletion by creating a new temporary layer
    VSILFILE *fpNew;
    const char *pszTempfile=CPLGenerateTempFilename(0);
    fpNew=VSIFOpenL(pszTempfile,"wb+");
    if( fpNew == NULL ) {
        CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open temporary file %s with write access, %s.",pszTempfile, VSIStrerror( errno ) );
        return OGRERR_FAILURE;
    } 
    if (Selafin::write_header(fpNew,poHeader)==0) {
        VSIFCloseL(fpNew);
        VSIUnlink(pszTempfile);
        return OGRERR_FAILURE;
    }
    long nLen;
    double dfDate;
    double *padfValues;
    for (long i=0;i<poHeader->nSteps;++i) {
        if (Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::read_float(poHeader->fp,dfDate)==0 ||
                Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::write_integer(fpNew,4)==0 ||
                Selafin::write_float(fpNew,dfDate)==0 ||
                Selafin::write_integer(fpNew,4)==0) {
            VSIFCloseL(fpNew);
            VSIUnlink(pszTempfile);
            return OGRERR_FAILURE;
        }
        for (long j=0;j<poHeader->nVar;++j) {
            if (Selafin::read_floatarray(poHeader->fp,&padfValues)==-1) {
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            if (eType==POINTS) {
                for (long k=(long)nFID;k<=poHeader->nPoints;++k) padfValues[k-1]=padfValues[k];
            }
            if (Selafin::write_floatarray(fpNew,padfValues,poHeader->nPoints)==0) {
                CPLFree(padfValues);
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            CPLFree(padfValues);   
        }
    }

    // If everything went fine, we overwrite the new file with the content of the old one. This way, even if something goes bad, we can still recover the layer. The copy process is format-agnostic.
    MoveOverwrite(poHeader->fp,fpNew);
    VSIUnlink(pszTempfile);
    return OGRERR_NONE;
    
}
Пример #4
0
OGRErr OGRSelafinLayer::CreateField(OGRFieldDefn *poField,
                                    CPL_UNUSED int bApproxOK) {
    CPLDebug("Selafin","CreateField(%s,%s)",poField->GetNameRef(),OGRFieldDefn::GetFieldTypeName(poField->GetType()));
    // Test if the field does not exist yet
    if (poFeatureDefn->GetFieldIndex(poField->GetNameRef())!=-1) {
        // Those two lines are copied from CSV driver, but I am not quite sure what they actually do
        if (poFeatureDefn->GetGeomFieldIndex(poField->GetNameRef())!=-1) return OGRERR_NONE;
        if (poFeatureDefn->GetGeomFieldIndex(CPLSPrintf("geom_%s",poField->GetNameRef()))!=-1) return OGRERR_NONE;
        CPLError(CE_Failure,CPLE_AppDefined,"Attempt to create field %s, but a field with this name already exists.",poField->GetNameRef());
        return OGRERR_FAILURE;
    }
    // Test if the field type is legal (only double precision values are allowed)
    if (poField->GetType()!=OFTReal) {
        CPLError(CE_Failure,CPLE_AppDefined,"Attempt to create field of type %s, but this is not supported for Selafin files (only double precision fields are allowed).",poField->GetFieldTypeName(poField->GetType()));
        return OGRERR_FAILURE;
    }
    if (VSIFSeekL(poHeader->fp,poHeader->getPosition(0),SEEK_SET)!=0) return OGRERR_FAILURE;
    // Change the header to add the new field
    poHeader->nVar++;
    poHeader->setUpdated();
    poHeader->papszVariables=(char**)CPLRealloc(poHeader->papszVariables,sizeof(char*)*poHeader->nVar);
    poHeader->papszVariables[poHeader->nVar-1]=(char*)VSIMalloc2(sizeof(char),33);
    strncpy(poHeader->papszVariables[poHeader->nVar-1],poField->GetNameRef(),32);
    poHeader->papszVariables[poHeader->nVar-1][32]=0;
    poFeatureDefn->AddFieldDefn(poField);

    // Now comes the real insertion. Since values have to be inserted nearly everywhere in the file and we don't want to store everything in memory to overwrite it, we create a new copy of it where we write the new values
    VSILFILE *fpNew;
    const char *pszTempfile=CPLGenerateTempFilename(0);
    fpNew=VSIFOpenL(pszTempfile,"wb+");
    if( fpNew == NULL ) {
        CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open temporary file %s with write access, %s.",pszTempfile, VSIStrerror( errno ) );
        return OGRERR_FAILURE;
    } 
    if (Selafin::write_header(fpNew,poHeader)==0) {
        VSIFCloseL(fpNew);
        VSIUnlink(pszTempfile);
        return OGRERR_FAILURE;
    }
    long nLen;
    double dfDate;
    double *padfValues;
    for (long i=0;i<poHeader->nSteps;++i) {
        if (Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::read_float(poHeader->fp,dfDate)==0 ||
                Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::write_integer(fpNew,4)==0 ||
                Selafin::write_float(fpNew,dfDate)==0 ||
                Selafin::write_integer(fpNew,4)==0) {
            VSIFCloseL(fpNew);
            VSIUnlink(pszTempfile);
            return OGRERR_FAILURE;
        }
        for (long j=0;j<poHeader->nVar-1;++j) {
            if (Selafin::read_floatarray(poHeader->fp,&padfValues)==-1) {
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            if (Selafin::write_floatarray(fpNew,padfValues,poHeader->nPoints)==0) {
                CPLFree(padfValues);
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            CPLFree(padfValues);   
        }
        padfValues=(double*)VSIMalloc2(sizeof(double),poHeader->nPoints);
        for (long k=0;k<poHeader->nPoints;++k) padfValues[k]=0;
        if (Selafin::write_floatarray(fpNew,padfValues,poHeader->nPoints)==0) {
            CPLFree(padfValues);
            VSIFCloseL(fpNew);
            VSIUnlink(pszTempfile);
            return OGRERR_FAILURE;
        }
        CPLFree(padfValues);   
    }
    MoveOverwrite(poHeader->fp,fpNew);
    VSIUnlink(pszTempfile);
    return OGRERR_NONE;
}
Пример #5
0
OGRErr OGRSelafinLayer::ICreateFeature(OGRFeature *poFeature) {
    OGRGeometry *poGeom=poFeature->GetGeometryRef();
    if (poGeom==0) return OGRERR_FAILURE;
    if (VSIFSeekL(poHeader->fp,poHeader->getPosition(0),SEEK_SET)!=0) return OGRERR_FAILURE;
    if (eType==POINTS) {
        // If it's a point layer, it's the "easy" case: we add a new point feature and update the file
        if (poGeom->getGeometryType()!=wkbPoint) {
            CPLError( CE_Failure, CPLE_AppDefined, "The new feature should be of the same Point geometry as the existing ones in the layer.");
            return OGRERR_FAILURE;
        }
        OGRPoint *poPoint=(OGRPoint*)poGeom;
        poFeature->SetFID(poHeader->nPoints);
        CPLDebug("Selafin","CreateFeature(%li,%f,%f)",poHeader->nPoints,poPoint->getX(),poPoint->getY());
        // Change the header to add the new feature
        poHeader->addPoint(poPoint->getX(),poPoint->getY());
    } else {
        // This is the most difficult case. The user wants to add a polygon element. First we check that it has the same number of vertices as the other polygon elements in the file. If there is no other element, then we define the number of vertices.
        // Every vertex in the layer should have a corresponding point in the corresponding point layer. So if we add a polygon element, we also have to add points in the corresponding layer.
        // The function tries to add as few new points as possible, reusing already existing points. This is generally what the user will expect.

        // First we check that we have the required geometry
        if (poGeom->getGeometryType()!=wkbPolygon) {
            CPLError( CE_Failure, CPLE_AppDefined, "The new feature should be of the same Polygon geometry as the existing ones in the layer.");
            return OGRERR_FAILURE;
        }

        // Now we check that we have the right number of vertices, or if this number was not defined yet (0), we define it at once
        OGRLinearRing *poLinearRing=((OGRPolygon*)poGeom)->getExteriorRing();
        poFeature->SetFID(poHeader->nElements);
        CPLDebug("Selafin","CreateFeature(" CPL_FRMT_GIB ",%f,%f,%f,%f,%f,%f)",poFeature->GetFID(),poLinearRing->getX(0),poLinearRing->getY(0),poLinearRing->getX(1),poLinearRing->getY(1),poLinearRing->getX(2),poLinearRing->getY(2));   //!< This is not safe as we can't be sure there are at least three vertices in the linear ring, but we can assume that for a debug mode
        int nNum=poLinearRing->getNumPoints();
        if (poHeader->nPointsPerElement==0) {
            if (nNum<4) {
                CPLError( CE_Failure, CPLE_AppDefined, "The new feature should have at least 3 vertices.");
                return OGRERR_FAILURE;
            }
            poHeader->nPointsPerElement=nNum-1;
            if (poHeader->nElements>0) {
                poHeader->panConnectivity=(long*)CPLRealloc(poHeader->panConnectivity,poHeader->nElements*poHeader->nPointsPerElement);
                if (poHeader->panConnectivity==0) return OGRERR_FAILURE;
            }
        } else {
            if (poLinearRing->getNumPoints()!=poHeader->nPointsPerElement+1) {
                CPLError( CE_Failure, CPLE_AppDefined, "The new feature should have the same number of vertices %li as the existing ones in the layer.",poHeader->nPointsPerElement);
                return OGRERR_FAILURE;
            }
        }

        // Now we look for vertices that are already referenced as points in the file
        int *anMap;
        anMap=(int*)VSIMalloc2(sizeof(int),poHeader->nPointsPerElement);
        if (anMap==0) {
            CPLError(CE_Failure,CPLE_AppDefined,"%s","Not enough memory for operation");
            return OGRERR_FAILURE;
        }
        for (long i=0;i<poHeader->nPointsPerElement;++i) anMap[i]=-1;
        if (poHeader->nPoints>0) {
            CPLRectObj *poBB=poHeader->getBoundingBox();
            double dfMaxDist=(poBB->maxx-poBB->minx)/sqrt((double)(poHeader->nPoints))/1000.0;   //!< Heuristic approach to estimate a maximum distance such that two points are considered equal if they are closer from each other
            dfMaxDist*=dfMaxDist;
            delete poBB;
            for (long i=0;i<poHeader->nPointsPerElement;++i) anMap[i]=poHeader->getClosestPoint(poLinearRing->getX(i),poLinearRing->getY(i),dfMaxDist);
        }

        // We add new points if needed only
        for (long i=0;i<poHeader->nPointsPerElement;++i) if (anMap[i]==-1) {
            poHeader->addPoint(poLinearRing->getX(i),poLinearRing->getY(i));
            anMap[i]=poHeader->nPoints-1;
        }

        // And we update the connectivity table to add the new element
        poHeader->nElements++;
        poHeader->panConnectivity=(long*)CPLRealloc(poHeader->panConnectivity,sizeof(long)*poHeader->nPointsPerElement*poHeader->nElements);
        for (long i=0;i<poHeader->nPointsPerElement;++i) {
            poHeader->panConnectivity[poHeader->nPointsPerElement*(poHeader->nElements-1)+i]=anMap[i]+1;
        }
        poHeader->setUpdated();
        CPLFree(anMap);
        
    }

    // Now comes the real insertion. Since values have to be inserted nearly everywhere in the file and we don't want to store everything in memory to overwrite it, we create a new copy of it where we write the new values
    VSILFILE *fpNew;
    const char *pszTempfile=CPLGenerateTempFilename(0);
    fpNew=VSIFOpenL(pszTempfile,"wb+");
    if( fpNew == NULL ) {
        CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open temporary file %s with write access, %s.",pszTempfile, VSIStrerror( errno ) );
        return OGRERR_FAILURE;
    } 
    if (Selafin::write_header(fpNew,poHeader)==0) {
        VSIFCloseL(fpNew);
        VSIUnlink(pszTempfile);
        return OGRERR_FAILURE;
    }
    long nLen;
    double dfDate;
    double *padfValues;
    for (long i=0;i<poHeader->nSteps;++i) {
        if (Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::read_float(poHeader->fp,dfDate)==0 ||
                Selafin::read_integer(poHeader->fp,nLen,true)==0 ||
                Selafin::write_integer(fpNew,4)==0 ||
                Selafin::write_float(fpNew,dfDate)==0 ||
                Selafin::write_integer(fpNew,4)==0) {
            VSIFCloseL(fpNew);
            VSIUnlink(pszTempfile);
            return OGRERR_FAILURE;
        }
        for (long j=0;j<poHeader->nVar;++j) {
            if (Selafin::read_floatarray(poHeader->fp,&padfValues)==-1) {
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            padfValues=(double*)CPLRealloc(padfValues,sizeof(double)*poHeader->nPoints);
            if (padfValues==NULL) {
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            if (eType==POINTS) padfValues[poHeader->nPoints-1]=poFeature->GetFieldAsDouble(j);
            else padfValues[poHeader->nPoints-1]=0;
            if (Selafin::write_floatarray(fpNew,padfValues,poHeader->nPoints)==0) {
                CPLFree(padfValues);
                VSIFCloseL(fpNew);
                VSIUnlink(pszTempfile);
                return OGRERR_FAILURE;
            }
            CPLFree(padfValues);   
        }
    }

    // If everything went fine, we overwrite the new file with the content of the old one. This way, even if something goes bad, we can still recover the layer. The copy process is format-agnostic.
    MoveOverwrite(poHeader->fp,fpNew);
    VSIUnlink(pszTempfile);
    return OGRERR_NONE;
}
Пример #6
0
INT cmd_move (LPTSTR param)
{
	LPTSTR *arg;
	INT argc, i, nFiles;
	LPTSTR pszDest;
	TCHAR szDestPath[MAX_PATH];
	TCHAR szFullDestPath[MAX_PATH];
	TCHAR szSrcDirPath[MAX_PATH];
	TCHAR szSrcPath[MAX_PATH];
	TCHAR szFullSrcPath[MAX_PATH];
	DWORD dwFlags = 0;
	INT nOverwrite = 0;
	WIN32_FIND_DATA findBuffer;
	HANDLE hFile;
	
	/* used only when source and destination  directories are on different volume*/
	HANDLE hDestFile;
	WIN32_FIND_DATA findDestBuffer;
	TCHAR szMoveDest[MAX_PATH];
	TCHAR szMoveSrc[MAX_PATH];
	LPTSTR pszDestDirPointer;
	LPTSTR pszSrcDirPointer;
	INT nDirLevel = 0;
	
	LPTSTR pszFile;
	BOOL OnlyOneFile;
	BOOL FoundFile;
	BOOL MoveStatus;
	DWORD dwMoveFlags = 0;
	DWORD dwMoveStatusFlags = 0;


	if (!_tcsncmp (param, _T("/?"), 2))
	{
#if 0
		ConOutPuts (_T("Moves files and renames files and directories.\n\n"
			"To move one or more files:\n"
			"MOVE [/N][/Y|/-Y][drive:][path]filename1[,...] destination\n"
			"\n"
			"To rename a directory:\n"
			"MOVE [/N][/Y|/-Y][drive:][path]dirname1 dirname2\n"
			"\n"
			"  [drive:][path]filename1  Specifies the location and name of the file\n"
			"                           or files you want to move.\n"
			"  /N                       Nothing. Don everthing but move files or direcories.\n"
			"  /Y\n"
			"  /-Y\n"
			"..."));
#else
		ConOutResPaging(TRUE,STRING_MOVE_HELP2);
#endif
		return 0;
	}

	nErrorLevel = 0;
	arg = splitspace(param, &argc);

	/* read options */
	for (i = 0; i < argc; i++)
	{
		if (!_tcsicmp(arg[i], _T("/N")))
			dwFlags |= MOVE_NOTHING;
		else if (!_tcsicmp(arg[i], _T("/Y")))
			dwFlags |= MOVE_OVER_YES;
		else if (!_tcsicmp(arg[i], _T("/-Y")))
			dwFlags |= MOVE_OVER_NO;
		else
			break;
	}
	nFiles = argc - i;

	if (nFiles < 1)
	{
		/* there must be at least one pathspec */
		error_req_param_missing();
		freep(arg);
		return 1;
	}

	if (nFiles > 2)
	{
		/* there are more than two pathspecs */
		error_too_many_parameters(param);
		freep(arg);
		return 1;
	}

	/* If no destination is given, default to current directory */
	pszDest = (nFiles == 1) ? _T(".") : arg[i + 1];

	/* check for wildcards in source and destination */
	if (_tcschr(pszDest, _T('*')) != NULL || _tcschr(pszDest, _T('?')) != NULL)
	{
		/* '*'/'?' in dest, this doesnt happen.  give folder name instead*/
		error_invalid_parameter_format(pszDest);
		freep(arg);
		return 1;
	}
	if (_tcschr(arg[i], _T('*')) != NULL || _tcschr(arg[i], _T('?')) != NULL)
	{
		dwMoveStatusFlags |= MOVE_SOURCE_HAS_WILD;
	}
	
	
	/* get destination */
	GetFullPathName (pszDest, MAX_PATH, szDestPath, NULL);
	TRACE ("Destination: %s\n", debugstr_aw(szDestPath));
	
	/* get source folder */
	GetFullPathName(arg[i], MAX_PATH, szSrcDirPath, &pszFile);
	if (pszFile != NULL)
		*pszFile = _T('\0');
	TRACE ("Source Folder: %s\n", debugstr_aw(szSrcDirPath));
	
	hFile = FindFirstFile (arg[i], &findBuffer);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		ErrorMessage (GetLastError (), arg[i]);
		freep (arg);
		return 1;
		
	}

	/* check for special cases "." and ".." and if found skip them */
	FoundFile = TRUE;
	while(FoundFile &&
		  (_tcscmp(findBuffer.cFileName,_T(".")) == 0 ||
		   _tcscmp(findBuffer.cFileName,_T("..")) == 0))
		FoundFile = FindNextFile (hFile, &findBuffer);
	
	if (!FoundFile)
	{
		/* what? we don't have anything to move? */
		error_file_not_found();
		FindClose(hFile);
		freep(arg);
		return 1;
	}
	
	OnlyOneFile = TRUE;
	/* check if there can be found files as files have first priority */
	if (findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		dwMoveStatusFlags |= MOVE_SOURCE_IS_DIR;
	else
		dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE;
	while(OnlyOneFile && FindNextFile(hFile,&findBuffer))
	{
		if (!(findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
		{
			ConOutPrintf(_T(""));
			if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) OnlyOneFile = FALSE;
			else
			{	/* this has been done this way so that we don't disturb other settings if they have been set before this */
				dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE;
				dwMoveStatusFlags &= ~MOVE_SOURCE_IS_DIR;
			}
		}
	}
	FindClose(hFile);

	TRACE ("Do we have only one file: %s\n", OnlyOneFile ? "TRUE" : "FALSE");

	/* we have to start again to be sure we don't miss any files or folders*/
	hFile = FindFirstFile (arg[i], &findBuffer);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		ErrorMessage (GetLastError (), arg[i]);
		freep (arg);
		return 1;
		
	}
	
	/* check for special cases "." and ".." and if found skip them */
	FoundFile = TRUE;
	while(FoundFile &&
		  (_tcscmp(findBuffer.cFileName,_T(".")) == 0 ||
		   _tcscmp(findBuffer.cFileName,_T("..")) == 0))
		FoundFile = FindNextFile (hFile, &findBuffer);
	
	if (!FoundFile)
	{
		/* huh? somebody removed files and/or folders which were there */
		error_file_not_found();
		FindClose(hFile);
		freep(arg);
		return 1;
	}
	
	/* check if source and destination paths are on different volumes */
	if (szSrcDirPath[0] != szDestPath[0])
		dwMoveStatusFlags |= MOVE_PATHS_ON_DIF_VOL;
	
	/* move it */
	do
	{
		TRACE ("Found file/directory: %s\n", debugstr_aw(findBuffer.cFileName));
		nOverwrite = 1;
		dwMoveFlags = 0;
		dwMoveStatusFlags &= ~MOVE_DEST_IS_FILE &
							~MOVE_DEST_IS_DIR &
							~MOVE_SRC_CURRENT_IS_DIR &
							~MOVE_DEST_EXISTS;
		_tcscpy(szFullSrcPath,szSrcDirPath);
		if(szFullSrcPath[_tcslen(szFullSrcPath) -  1] != _T('\\'))
			_tcscat (szFullSrcPath, _T("\\"));
		_tcscat(szFullSrcPath,findBuffer.cFileName);
		_tcscpy(szSrcPath, szFullSrcPath);
		
		if (IsExistingDirectory(szSrcPath))
		{
			/* source is directory */
			
			if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE)
			{
				dwMoveStatusFlags |= MOVE_SRC_CURRENT_IS_DIR; /* source is file but at the current round we found a directory */
				continue;
			}
			TRACE ("Source is dir: %s\n", debugstr_aw(szSrcPath));
			dwMoveFlags = MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
		}
		
		/* if source is file we don't need to do anything special */
		
		if (IsExistingDirectory(szDestPath))
		{
			/* destination is existing directory */
			TRACE ("Destination is directory: %s\n", debugstr_aw(szDestPath));
			
			dwMoveStatusFlags |= MOVE_DEST_IS_DIR;
			
			/*build the dest string(accounts for *)*/
			_tcscpy (szFullDestPath, szDestPath);
			/*check to see if there is an ending slash, if not add one*/
			if(szFullDestPath[_tcslen(szFullDestPath) -  1] != _T('\\'))
				_tcscat (szFullDestPath, _T("\\"));
			_tcscat (szFullDestPath, findBuffer.cFileName);
			
			if (IsExistingFile(szFullDestPath) || IsExistingDirectory(szFullDestPath))
				dwMoveStatusFlags |= MOVE_DEST_EXISTS;
			
			dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
			
		}
		if (IsExistingFile(szDestPath))
		{
			/* destination is a file */
			TRACE ("Destination is file: %s\n", debugstr_aw(szDestPath));
			
			dwMoveStatusFlags |= MOVE_DEST_IS_FILE | MOVE_DEST_EXISTS;
			_tcscpy (szFullDestPath, szDestPath);
			
			dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
			
		}
		
		TRACE ("Move Status Flags: 0x%X\n",dwMoveStatusFlags);
		
		if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR &&
			dwMoveStatusFlags & MOVE_DEST_IS_DIR &&
			dwMoveStatusFlags & MOVE_SOURCE_HAS_WILD)
		{
			/* We are not allowed to have existing source and destination dir when there is wildcard in source */
			error_syntax(NULL);
			FindClose(hFile);
			freep(arg);
			return 1;
		}
			
		if (!(dwMoveStatusFlags & (MOVE_DEST_IS_FILE | MOVE_DEST_IS_DIR)))
		{
			/* destination doesn't exist */
			_tcscpy (szFullDestPath, szDestPath);
			if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) dwMoveStatusFlags |= MOVE_DEST_IS_FILE;
			if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) dwMoveStatusFlags |= MOVE_DEST_IS_DIR;
			
			dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
		}
		
		if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE &&
			dwMoveStatusFlags & MOVE_DEST_IS_FILE &&
			!OnlyOneFile)
		{
			/*source has many files but there is only one destination file*/
			error_invalid_parameter_format(pszDest);
			FindClose(hFile);
			freep (arg);
			return 1;
		}
		
		/*checks to make sure user wanted/wants the override*/
		if((dwFlags & MOVE_OVER_NO) &&
		   (dwMoveStatusFlags & MOVE_DEST_EXISTS))
			continue;
		if(!(dwFlags & MOVE_OVER_YES) &&
		    (dwMoveStatusFlags & MOVE_DEST_EXISTS))
			nOverwrite = MoveOverwrite (szFullDestPath);
		if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
			continue;
		if (nOverwrite == PROMPT_ALL)
			dwFlags |= MOVE_OVER_YES;
		
			
		ConOutPrintf (_T("%s => %s "), szSrcPath, szFullDestPath);
		
		/* are we really supposed to do something */
		if (dwFlags & MOVE_NOTHING)
			continue;
		
		/*move the file*/
		if (!(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR &&
			dwMoveStatusFlags & MOVE_PATHS_ON_DIF_VOL))
			/* we aren't moving source folder to different drive */
			MoveStatus = MoveFileEx (szSrcPath, szFullDestPath, dwMoveFlags);
		else
		{	/* we are moving source folder to different drive */
			_tcscpy(szMoveDest, szFullDestPath);
			_tcscpy(szMoveSrc, szSrcPath);
			DeleteFile(szMoveDest);
			MoveStatus = CreateDirectory(szMoveDest, NULL); /* we use default security settings */
			if (MoveStatus)
			{
				_tcscat(szMoveDest,_T("\\"));
				_tcscat(szMoveSrc,_T("\\"));
				nDirLevel = 0;
				pszDestDirPointer = szMoveDest + _tcslen(szMoveDest);
				pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc);
				_tcscpy(pszSrcDirPointer,_T("*.*"));
				hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer);
				if (hDestFile == INVALID_HANDLE_VALUE)
					MoveStatus = FALSE;
				else
				{
					BOOL FirstTime = TRUE;
					FoundFile = TRUE;
					MoveStatus = FALSE;
					while(FoundFile)
					{
						if (FirstTime)
							FirstTime = FALSE;
						else
							FoundFile = FindNextFile (hDestFile, &findDestBuffer);
						
						if (!FoundFile)
						{	/* Nothing to do in this folder so we stop working on it */
							FindClose(hDestFile);
							(pszSrcDirPointer)--;
							(pszDestDirPointer)--;
							_tcscpy(pszSrcDirPointer,_T(""));
							_tcscpy(pszDestDirPointer,_T(""));
							if (nDirLevel > 0)
							{
								TCHAR szTempPath[MAX_PATH];
								INT nDiff;

								FoundFile = TRUE; /* we need to continue our seek for files */
								nDirLevel--;
								RemoveDirectory(szMoveSrc);
								GetDirectory(szMoveSrc,szTempPath,0);
								nDiff = _tcslen(szMoveSrc) - _tcslen(szTempPath);
								pszSrcDirPointer = pszSrcDirPointer - nDiff;
								_tcscpy(pszSrcDirPointer,_T(""));
								GetDirectory(szMoveDest,szTempPath,0);
								nDiff = _tcslen(szMoveDest) - _tcslen(szTempPath);
								pszDestDirPointer = pszDestDirPointer - nDiff;
								_tcscpy(pszDestDirPointer,_T(""));
								if(szMoveSrc[_tcslen(szMoveSrc) -  1] != _T('\\'))
									_tcscat (szMoveSrc, _T("\\"));
								if(szMoveDest[_tcslen(szMoveDest) -  1] != _T('\\'))
									_tcscat (szMoveDest, _T("\\"));
								pszDestDirPointer = szMoveDest + _tcslen(szMoveDest);
								pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc);
								_tcscpy(pszSrcDirPointer,_T("*.*"));
								hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer);
								if (hDestFile == INVALID_HANDLE_VALUE)
									continue;
								FirstTime = TRUE;
							}
							else
							{
								MoveStatus = TRUE; /* we moved everything so lets tell user about it */
								RemoveDirectory(szMoveSrc);
							}
							continue;
						}
						
						/* if we find "." or ".." we'll skip them */
						if (_tcscmp(findDestBuffer.cFileName,_T(".")) == 0 ||
							_tcscmp(findDestBuffer.cFileName,_T("..")) == 0)
							continue;
					
						_tcscpy(pszSrcDirPointer, findDestBuffer.cFileName);
						_tcscpy(pszDestDirPointer, findDestBuffer.cFileName);
						if (IsExistingFile(szMoveSrc))
						{
							FoundFile = CopyFile(szMoveSrc, szMoveDest, FALSE);
							if (!FoundFile) continue;
							DeleteFile(szMoveSrc);
						}
						else
						{
							FindClose(hDestFile);
							CreateDirectory(szMoveDest, NULL);
							_tcscat(szMoveDest,_T("\\"));
							_tcscat(szMoveSrc,_T("\\"));
							nDirLevel++;
							pszDestDirPointer = szMoveDest + _tcslen(szMoveDest);
							pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc);
							_tcscpy(pszSrcDirPointer,_T("*.*"));
							hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer);
							if (hDestFile == INVALID_HANDLE_VALUE)
							{
								FoundFile = FALSE;
								continue;
							}
							FirstTime = TRUE;
						}
					}
				}
			}
		}
		if (MoveStatus)
			ConOutResPrintf(STRING_MOVE_ERROR1);
		else
			ConOutResPrintf(STRING_MOVE_ERROR2);
	}
	while ((!OnlyOneFile || dwMoveStatusFlags & MOVE_SRC_CURRENT_IS_DIR ) &&
			!(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) &&
			FindNextFile (hFile, &findBuffer));
	FindClose (hFile);
	
	freep (arg);
	return 0;
}